読者です 読者をやめる 読者になる 読者になる

Wicket-GuiceでUnitテスト時にインジェクションの設定を変える

DIを使うことのメリットの一つにテスト容易性の向上があります。
Wicket-Guiceを利用すると設定ファイルレスにDIを実現できますが、一方でxml等で設定が外出しになっていないので、テストでスタブをインジェクションしたいというときにxmlでインジェクトの設定なんかを変えることが出来ません。

で、どうすれば良いのかなぁーと考えた結果こんな感じになりました。

public class WicketApplication extends WebApplication {
	public WicketApplication() {
	}
	public Class getHomePage() {
		return HomePage.class;
	}
	@Override
	protected void init() {
		initGuice();
	}
	protected void initGuice() {
		addComponentInstantiationListener(new GuiceComponentInjector(this));
	}
}
public class HomePage extends WebPage {
	@Inject
	private Service service;
	public HomePage(final PageParameters parameters) {
		add(new Label("message", service.getMessage()));
	}
}
@ImplementedBy(ServiceImpl.class)
public interface Service {
	public String getMessage();
}
@Singleton
public class ServiceImpl implements Service {
	public String getMessage() {
		return "Hello World!";
	}
}

上記を実行すると、「Hello World!」が表示されます。

でテストするとき。
こんなスタブを作ったとする。

public class DummyService implements Service {
	public String getMessage() {
		return "dummy";
	}
}

これをテストケースで以下のように設定してみた。

public class TestHomePage extends TestCase {
	private WicketTester tester;
	public void setUp() {
		tester = new WicketTester(new WicketApplication() {
			@Override
			protected void initGuice() {
				addComponentInstantiationListener(new GuiceComponentInjector(
						this, getModule()));

			}
			protected Module getModule() {
				return new Module() {
					public void configure(Binder binder) {
						// テスト時に変えたいインジェクションの設定を記述する。
						binder.bind(Service.class).to(DummyService.class).in(Scopes.SINGLETON);
					}
				};
			}
		});
	}
	public void testRenderMyPage() {
		tester.startPage(HomePage.class);
		tester.assertRenderedPage(HomePage.class);
		tester.assertLabel("message", "dummy");
	}
}

これでテスト実行時にはDummyServiceがインジェクションされます。
WicketApplicationにgetModule()を実装して、テストケース側でOverrideすることも考えましたが、アノテーションだけでインジェクションの設定が済んでしまう場合は不要なメソッドになってしまうので、initGuice()というメソッドだけ実装して、テストケース側でOverrideするようにしてみました。

こんなんで良いのかな><
だれか、もっと良い方法があったら教えてください。