Dagger2禁用AndroidInjection.inject(this);用于仪器测试

时间:2017-09-10 20:47:36

标签: android testing dagger-2

使用最新的Dagger2,我们可以通过以下代码注入依赖项:

public class BaseActivity extends LifecycleActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
    }
}

需要DI继承自此BaseClass的其他活动。 对于我的仪器测试,我不想使用Dagger,我只能模拟对象。

我的仪器测试设置(我目前正在测试LoginActivity,它扩展了BaseActivity)并不特别,如下所示:

TestRunner:

public class LivefeedTestRunner extends AndroidJUnitRunner{
    @Override
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return super.newApplication(cl, TestApp.class.getName(), context);
    }
}

TestApp:

public class TestApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
    }
}

问题是运行检测测试会导致错误:

引起:java.lang.RuntimeException:com.example.kimgysen.livefeed_v002.TestApp没有实现dagger.android.HasActivityInjector 在dagger.android.AndroidInjection.inject(AndroidInjection.java:48) 在com.example.kimgysen.livefeed_v002.ui.BaseActivity.onCreate(BaseActivity.java:12) 在com.example.kimgysen.livefeed_v002.ui.login.LoginActivity.onCreate(LoginActivity.java:32) 在android.app.Activity.performCreate(Activity.java:6237) 在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 在android.support.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:624) 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) ... 9更多

指向以下行:

public class BaseActivity extends LifecycleActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this); // <-- this line 
        super.onCreate(savedInstanceState);
    }
}

知道如何轻易绕过这个吗? 在我的应用程序本身,我实现dagger.android.HasActivityInjector,但我不需要它用于我的仪器测试。

2 个答案:

答案 0 :(得分:4)

我通过创建一个虚假的activityInjector解决了这个问题,如下文所示: https://github.com/google/dagger/blob/master/javatests/dagger/android/AndroidInjectionTest.java#L60

(相当于fakeActivityInjector)

public class TestApp extends Application implements HasActivityInjector {
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return fakeActivityInjector("injected by app");
    }

    public static class InjectableActivity extends Activity {
        String tag;
    }

    private static AndroidInjector<Activity> fakeActivityInjector(String tag) {
        return instance -> {
            if (instance instanceof InjectableActivity) {
                ((InjectableActivity) instance).tag = tag;
            }
        };
    }
}

答案 1 :(得分:0)

Github上的android-architecture-components样本中有另一种解决方案。

他们inject活动通过ActivityLifecycleCallbacks。对于检测测试,他们使用TestApp注册ActivityLifecycleCallbacks,因此它不会注入任何内容。

请参阅https://stackoverflow.com/a/48101811/1552622