java - Robolectric - 应用程序在设置中有单例,导致测试问题

标签 java android unit-testing robolectric

我目前继承了一个代码覆盖率为零的 Android 应用程序,我的第一份工作是为它编写一些单元测试。所以我决定也以此为契机学习 Robolectric。

但是,我在运行两个简单的虚拟测试时遇到了初始问题。

这是我的测试文件中的代码:

@Config(constants = BuildConfig.class)
@RunWith(RobolectricGradleTestRunner.class)
public class SplashActivityTest {

private SplashActivity activity;

// @Before => JUnit 4 annotation that specifies this method should run before each test is run
// Useful to do setup for objects that are needed in the test
@Before
public void setup() {
    // Convenience method to run SplashActivity through the Activity Lifecycle methods:
    // onCreate(...) => onStart() => onPostCreate(...) => onResume()
    activity = Robolectric.setupActivity(SplashActivity.class);
}

// @Test => JUnit 4 annotation specifying this is a test to be run
// Checking that the UI gets setup correctly
@Test
public void dummy() {
  String test = "POP!";

    assertTrue("POP!",
            test.equals("POP!"));
}

@Test
public void dummyTwo() {

    String test = "POP!!";

    assertTrue("POP!!",
            test.equals("POP!!"));
}

}

问题是该 Activity 扩展了另一个名为 baseactivity 的类,并且在该类中使用了自定义 Application 类。

在此自定义应用程序类中,使用以下代码将 Picasso 创建为单例:

picasso = new Picasso.Builder(getApplicationContext()).downloader(new OkHttpDownloader(picassoClient)).build();
    Picasso.setSingletonInstance(picasso);

当我运行测试时,出现以下错误:

java.lang.IllegalStateException: Singleton instance already exists. at com.squareup.picasso.Picasso.setSingletonInstance(Picasso.java:677)

所以看起来应用程序类被创建了两次,一次是针对每个测试,一次是运行良好的测试。所以我假设我的测试模式在这里是错误的?谁能帮我找出正确的模式?与单元测试一样,我只想测试有限的功能,所以我不确定我在做什么是正确的。

编辑:我试图设置一个“模拟”应用程序类并让 Robolectric 使用它,但它似乎仍然使用真正的应用程序类。

所以在 test/java 中我有以下类:

public class TestMyApplication extends MyApplication
        implements TestLifecycleApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        initPicasso();
    }

    @Override
    protected void initPicasso() {
        //nothing to do
    }

    @Override public void beforeTest(Method method) {
    }

    @Override public void prepareTest(Object test) {
    }

    @Override public void afterTest(Method method) {
    }
}

如您所见,它扩展了我的主应用程序中的 MyApplication 类,我还在 initPicasso 方法中添加了 @Override 以试图阻止它被调用,但是当我运行测试时,我仍然得到错误Picasso Singleton 被设置为第二次测试。

因此,当我运行我的测试类时,它仍然进入我的主应用程序中的应用程序类,为什么 Robolectric 在单元测试的范围内应该受到限制时这样做?

我也试过这个:

@Config(constants = BuildConfig.class, application = TestMyApplication.class)

但是当我尝试这个并运行测试类时,我收到一条错误消息,说它找不到 TestMyApplication,所以关于为什么 Robolectric 不会使用我模拟的 Application 类,这是一个让我很头疼的问题。

最佳答案

在 Robolectric 3.4.2 中,在测试工作中使用自定义应用程序类:

public class MyApplication extends Application {

    protected void initPicasso() {
        // do Picasso initialization
    }

}

public class TestMyApplication extends MyApplication {

    @Override
    protected void initPicasso() {
        //nothing to do
    }

}

只需在您的测试类中添加一个 Config 注释:

@Config(constants = BuildConfig.class, application = TestMyApplication.class)

关于java - Robolectric - 应用程序在设置中有单例,导致测试问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37684113/

相关文章:

java - 如何在 Java 中获取时区的当前日期和时间?

java - 检查 Realm 对象是否有任何变化

c# - SOLID-原则的尝试,实不实?

c# - 单元测试 "No Symbol loaded"快把我逼疯了

java - 如何在 Java 中检测多项式

java - 将列表 A 中的元素添加到列表 B 的元素中,其中特殊成员相等

javascript - 仅限 Android Chrome : Changing input val during keyup doesn't apply

c# - 如何模拟在 using() block 中实例化的对象

java - 传输 DLList 的字符串时出现问题

Android:ListView 有奇怪的边距