DI の概念は完全に理にかなっているからです。DI の優れた「副産物」の 1 つは (Jake Wharton がプレゼンテーションの 1 つに述べたように)、テスト容易性です。
だから今、私は基本的に Espresso を使用していくつかの機能テストを行っており、ダミー/モック データをアプリケーションに挿入し、アクティビティにそれらを表示できるようにしたいと考えています。これは DI の最大の利点の 1 つであるため、比較的簡単な質問であると思います。しかし、なぜか頭が回らないようです。どんな助けでも大歓迎です。これが私がこれまでに持っているものです(現在の設定を反映する例を書きました):
public class MyActivity
extends MyBaseActivity {
@Inject Navigator _navigator;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApplication.get(this).inject(this);
// ...
setupViews();
}
private void setupViews() {
myTextView.setText(getMyLabel());
}
public String getMyLabel() {
return _navigator.getSpecialText(); // "Special Text"
}
}
これらは私の短剣モジュールです:
// Navigation Module
@Module(library = true)
public class NavigationModule {
private Navigator _nav;
@Provides
@Singleton
Navigator provideANavigator() {
if (_nav == null) {
_nav = new Navigator();
}
return _nav;
}
}
// App level module
@Module(
includes = { SessionModule.class, NavigationModule.class },
injects = { MyApplication.class,
MyActivity.class,
// ...
})
public class App {
private final Context _appContext;
AppModule(Context appContext) {
_appContext = appContext;
}
// ...
}
私のエスプレッソ テストでは、次のようなモック モジュールを挿入しようとしています。
public class MyActivityTest
extends ActivityInstrumentationTestCase2<MyActivity> {
public MyActivityTest() {
super(MyActivity.class);
}
@Override
public void setUp() throws Exception {
super.setUp();
ObjectGraph og = ((MyApplication) getActivity().getApplication()).getObjectGraph().plus(new TestNavigationModule());
og.inject(getActivity());
}
public void test_SeeSpecialText() {
onView(withId(R.id.my_text_view)).check(matches(withText(
"Special Dummy Text")));
}
@Module(includes = NavigationModule.class,
injects = { MyActivityTest.class, MyActivity.class },
overrides = true,
library = true)
static class TestNavigationModule {
@Provides
@Singleton
Navigator provideANavigator() {
return new DummyNavigator(); // that returns "Special Dummy Text"
}
}
}
これはまったく機能していません。私の Espresso テストは実行されますが、TestNavigationModule は完全に無視されます... arr... :(
私は何を間違っていますか?Espresso でモジュールをモックするより良い方法はありますか? Robolectric、Mockito などが使用されている例を検索して見ました。しかし、純粋な Espresso テストが必要なだけで、モジュールをモック モジュールと交換する必要があります。どうすればいいですか?
編集:
そこで、静的テスト モジュール リスト定義を作成し、null をチェックしてから Application クラスに追加する @ user3399328 アプローチを採用しました。ただし、クラスのテスト注入バージョンをまだ取得していません。しかし、私のエスプレッソライフサイクルではなく、短剣テストモジュールの定義に問題がある可能性があります。私が仮定している理由は、デバッグ ステートメントを追加し、静的テスト モジュールがアプリケーション クラスへの挿入時に空ではないことを発見したためです。私が間違っている可能性があることの方向性を教えてください。私の定義のコードスニペットは次のとおりです。
私のアプリケーション:
@Override
public void onCreate() {
// ...
mObjectGraph = ObjectGraph.create(Modules.list(this));
// ...
}
モジュール:
public class Modules {
public static List<Object> _testModules = null;
public static Object[] list(MyApplication app) {
// return new Object[]{ new AppModule(app) };
List<Object> modules = new ArrayList<Object>();
modules.add(new AppModule(app));
if (_testModules == null) {
Log.d("No test modules");
} else {
Log.d("Test modules found");
}
if (_testModules != null) {
modules.addAll(_testModules);
}
return modules.toArray();
}
}
私のテストクラス内の変更されたテストモジュール:
@Module(overrides = true, library = true)
public static class TestNavigationModule {
@Provides
@Singleton
Navigator provideANavigator()() {
Navigator navigator = new Navigator();
navigator.setSpecialText("Dummy Text");
return navigator;
}
}