2

我想用Espresso为一个Activity编写功能测试,使用使用MockRestAdapter(https://github.com/square/retrofit/blob/master/retrofit-mock/src/main/java/retrofit/MockRestAdapter.java)创建的模拟Retrofit API服务实例。将模拟改造API服务实例注入到ActivityInstrumentTestCase2中

虽然这是有点棘手,因为你不能通过Activity的构造函数注入任何依赖关系。

目前,单个Retrofit API服务实例位于我的Application对象中,并且在每个活动的“onCreate()”方法中创建一个对它的引用。

如何交换模拟Retrofit API服务?也许Dagger是答案?

+0

我正是这样做的!这里是我写的关于它的一篇文章(它没有提到Espresso,但除了测试将包含Espresso api调用外,完全一样)请参阅[使用Dagger,Retrofit和MockWebServer进行Android测试](http://systemdotrun.blogspot .co.uk/2014/11/android-testing-with-dagger-retrofit.html) – Dori 2014-11-22 20:11:44

+0

太棒了!很有帮助! – 2014-11-23 23:15:25

回答

5

是的,匕首就是答案。关于如何实现这一目标,我建议在Github看杰克沃顿的u2020。简而言之,您为生产和调试风格提供了不同的API实现。或者,你可以有一个独立的风格进行集成测试。

不用匕首来解决这个问题的另一种方法(增加对它的支持对于正在进行的项目来说是一项相当大的工作),将会有集成测试的味道。例如。有release,debugmock口味。

然后,您可以在Android Manifest中为mock设置不同的Application类别 - 使用模拟适配器的一种实现。这里的核心思想是,你可以重写或增加你的主要AndroidManifest的风味。

那会大致是这样的:

项目结构

app/ 
    src/ 
     main/ 
      AndroidManifest.xml - Activities, services, permissions - all the stuff goes here 
      java/.../MyApplication.java 
     mock/ 
      AndroidManifest.xml - example below 
      java/.../MockApplication.java 
     debug/ - Not relevant for this example 
     release/ - Not relevant for this example 

主/ AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    package="com.example.android" > 

    <!-- Permissions etc --> 

    <application 
     android:name=".MyApplication" 
     ... 
     > 

     <!-- Activities, services etc --> 

    </application> 
</manifest> 

模拟/ AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> 
    <application android:name=".MockApplication"/> 
</manifest> 

Application.java

public class MyApplication extends Application { 

    @Override public void onCreate(Bundle savedState) { 
     MyApi api = createApiAdapter(); 
    } 

    protected MyApi createApiAdapter() { 
     // Create regular Retrofit adapter 
    } 

} 

MockApplication.java

public class MockApplication extends MyApplication { 

    @Override protected MyApi createApiAdapter() { 
     // Create mock Retrofit adapter 
    } 

} 

的build.gradle

android { 

    // ... 

    buildTypes { 
     mock { 
      applicationIdSuffix '.mock' 
      versionNameSuffix '-mock' 
      debuggable true 
     } 
     debug { 
      applicationIdSuffix '.dev' 
      versionNameSuffix '-dev' 
      debuggable true 
     } 
     release { 
      signingConfig signingConfigs.release 
     } 
    } 
} 
+0

谢谢你!我没有意识到你可以在AndroidManifest中指定一个不同的'Application'。你能简单介绍一下如何做到这一点吗? – 2014-10-24 15:19:53

+1

增加了一些例子 - 从我脑海开始的伪代码,但你应该明白。后来我敦促你看一下u2020--用Dagger更好的解决方案。但是如果一旦开始使用它,就不会回来;) – mindeh 2014-10-24 16:42:46

+0

很酷,谢谢!是的,Dagger非常优雅,很酷。 – 2014-10-24 18:22:53

相关问题