Mortarを採用したプロジェクトでは各所でMortarScopeが必要になる.
MortarScopeはContext.getSystemServiceを経由して取得されるが, InstrumentationRegistry.getTargetContext()
で取得できるContextにはこれが実装されていないためMockオブジェクトを用意する必要がある.
以下はMotar/PresenterをテストするためのMortar/Viewのmockクラス.
MortarScopeを生成するためオリジナルのContextをContext.getSystemServiceのMock Methodを実装したContextWrapperでラップする.
あとはお決まりのEnter/ExitScope処理を実装すればMockは完成する.
private static class Viewer implements MyPresenter.MyViewer {
private Context context;
private MortarScope mortarScope;
private MyPresenter presenter;
public Viewer(Context context, MyPresenter presenter) {
// MortarScopeを返すラッパーを定義する.
this.context = new ContextWrapper(context) {
@Override
public Object getSystemService(String name) {
return mortarScope != null && mortarScope.hasService(name) ?
mortarScope.getService(name) : super.getSystemService(name);
}
};
this.presenter = presenter;
}
public void onCreate() {
// お決まりのスコープ定義とEnterScope処理.
String scopeName = "UnitTestScope";
mortarScope = MortarScope.buildRootScope().build("Root").buildChild()
.withService(BundleServiceRunner.SERVICE_NAME, new BundleServiceRunner())
.withService(ObjectGraphService.SERVICE_NAME, ObjectGraph.create(new AppHomeModule()))
.build(scopeName);
BundleServiceRunner.getBundleServiceRunner(getContext()).onCreate(null);
presenter.takeView(this);
}
public void onDestroy() {
// お決まりのExitScope処理.
presenter.dropView(this);
}
// MyPresenter.MyViewerの抽象メソッドを実装
@Override
public Context getContext() {
return context;
}
}
Mortar/Viewの生成と破棄はsetup/tearDownで実装した.
@Before
public void setup() throws Exception {
presenter = new MyPresenter();
viewer = new Viewer(InstrumentationRegistry.getTargetContext(), presenter);
viewer.onCreate();
}
@After
public void tearDown() {
viewer.onDestroy();
}
以上.