シングルトン クラスの単体テストを作成したいのですが、このクラスは UI コンポーネントに依存しています。このクラスにはPageManager
、ページ履歴を前後に移動する機能があります。単体テストでは、この履歴機能をテストするのが好きですが、このテストには必要ないため、UI のものを初期化したくありません。
私はJMockitが初めてで、これを試してみましたが、成功しませんでした:モックされる元のクラスは次のとおりです:
public final class PageManager {
private static final PageManager INSTANCE = new PageManager();
private final Set<Page> pages = new HashSet<>();
private Page currentPage;
private boolean initialized = false;
private PageManager() {
// Do some UI stuff
}
public static PageManager getInstance() {
return INSTANCE;
}
public void addPage(final Page page) {
pages.add(page);
}
public void initialize() {
// Do some UI stuff
initialized = true;
}
public Page getPage() { return currentPage; }
public void setPage(final Page page) { ... }
public void goBack() { ... };
public void goForward() { ... };
public boolean canGoBack() { ... };
public boolean canGoForward() { ... };
private void activatePage(final Page page) {
// Do some UI stuff
this.currentPage = page;
}
private void deactivatePage(final Page page) {
// Do some UI stuff
}
}
これは嘲笑されたバージョンです:
public final class MockedPageManager extends MockUp<PageManager> {
PageManager instance;
@Mock
void $init(final Invocation invocation) {
instance = invocation.getInvokedInstance();
}
@Mock
void initialize() {
// Don't do UI stuff
Deencapsulation.setField(instance, "initialized", true);
}
@Mock
void activatePage(Page page) {
Deencapsulation.setField(instance, "currentPage", page);
page.activate();
}
@Mock
void deactivatePage(Page page) {
}
}
そして小さなテスト:
@Test
public void testGoBack() {
new MockedPageManager();
final Page p1 = new Page() { @Override public String getTitle() { return "p1"; } };
final Page p2 = new Page() { @Override public String getTitle() { return "p2"; } };
final PageManager pm = PageManager.getInstance();
pm.addPage(p1);
pm.addPage(p2);
pm.initialize();
pm.setPage(p1)
assertEquals(p1, pm.getCurrentPage());
pm.setPage(p2);
assertEquals(p2, pm.getCurrentPage())
assertTrue(pm.canGoBack());
pm.goBack();
assertEquals(p1, pm.getCurrentPage());
}
このテストでは、$init
JMockit によってメソッドが正しく呼び出されます。問題は、が呼び出されたNullPointerExceptions
ときにテストで an がスローされることです。スタックトレースは、フィールドがpm.addPage(p1)
であるため、元のクラスで NPE が発生することを示しています。PageManager
Set pages
null
私の質問は: このシングルトン クラスは正しくモックされていますか? メソッドはコンストラクターのみをオーバーライドしますか、$init
それとも Java インスタンス初期化子もオーバーライドしますか。つまり、Set pages = new HashSet<>();