如何在每个单元测试中获取我的Application类的新实例?

Ogn*_*yan 12 android unit-testing

我有一个Android应用程序,其中包含MyApplication继承自的类Application.

我创建了几个运行的单元测试@RunWith(AndroidJUnit4.class).如果我单独运行每个测试,他们都会通过.如果我一起运行 - 第一个通过然后(其中一些)其他人失败.

问题是,似乎只MyApplication创建了一个实例,然后将其保留并用于导致失败的所有测试,因为其中只有一个状态MyApplication必须初始化一次.

有没有办法运行单元测试(androidTest)所以应用程序重新启动每个测试?我不在乎它是否会很慢(例如每次都必须重新安装应用程序)我只想让测试彼此独立运行.

单元测试的实际代码如下(根据@Zinc的要求):

@RunWith(AndroidJUnit4.class)
public class AutoLogin_ActMainTest {
    @Rule
    public ActivityTestRule<ActMain> mActivityRule = new ActivityTestRule<ActMain>(
            ActMain.class) {


        @Override
        protected void beforeActivityLaunched() {
            super.beforeActivityLaunched();

            MyTestApp app = (MyTestApp) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
            DependencyInjector.reset();
            app.reset();


            FakeUnitDaggerModule fudm = new FakeUnitDaggerModule();

            Session session = new SessionImpl(new TimeProviderImpl());
            fudm.setResMain(new ResMainTest(session));

            FakeAppPrefs appPrefs = new FakeAppPrefs();
            FakeLoginPrefs loginPrefs = new FakeLoginPrefs();
            CurrentUserHolder currentUserHolder = new CurrentUserHolder();

            FakeComponent inj = DaggerFakeComponent.builder().
                    fakeMyAppDaggerModule(new FakeMyAppDaggerModule(app, appPrefs, loginPrefs, currentUserHolder)).
                    appInfoDaggerModule(new AppInfoDaggerModule("1")).
                    fakeSessionDaggerModule(new FakeSessionDaggerModule(session)).
                    fakeExchangeDaggerModule(new FakeExchangeDaggerModule("https://test.com")).
                    fakeUnitDaggerModule(fudm).
                    build();

            DependencyInjector.init(inj);
            DependencyInjector.getInstance().inject(app);


            app.onStart();
        }
    };


    @Test
    public void testAutoLogin() {
        ElapsedTimeIdlingResource idlingResource = new ElapsedTimeIdlingResource(500);
        Espresso.registerIdlingResources(idlingResource);
        idlingResource.startWaiting();

        onView(ViewMatchers.withId(R.id.tv_logged_in_as)).check(matches(isDisplayed()));
        Espresso.unregisterIdlingResources(idlingResource);
    }
}
Run Code Online (Sandbox Code Playgroud)

Com*_*are 5

问题是似乎只创建了 MyApplication 的一个实例,然后将其保留并用于所有导致失败的测试,因为 MyApplication 中有一个状态必须仅初始化一次。

恕我直言,这是应用程序中的一个错误,应该修复。Application对于许多真正的业务逻辑来说,这是一个不合适的位置(尽管它可以用于初始化您的崩溃报告程序库StrictMode等)。其他所有内容都应该可以单独测试,可以是直接测试,也可以是通过模拟,也可以是通过依赖注入等。

话虽如此,有时问题不在于您控制的代码,而在于库或框架中的代码。

有没有办法运行单元测试(androidTest),以便为每个测试重新启动应用程序?

如今,是的,虽然在问这个问题的时候没有。在Android的测试Orchestrator的(ATO)做隔离每个测试,在测试执行速度的成本,更好的工作。