2014-01-27 60 views
0

我是Mockito新手,在嘗試模擬第三方類時遇到了錯誤。Mockito NullPointerException在InvocationMatcher上調用equals等於

堆棧跟蹤:

java.lang.NullPointerException 
at MockitoTest.equals(MockitoTest.java:34) 
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:58) 
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:75) 
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:87) 
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29) 
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38) 
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:51) 
at MockitoTest$$EnhancerByMockitoWithCGLIB$$cde393a2.getSomethingElse(<generated>) 
at MockitoTestTest.test(MockitoTestTest.java:19) 

時的Mockito調用這個模擬,不具有一些設置私有成員的equals方法。代碼:

public void test() { 
    final String something = "something"; 
    final String somethingElse = "somethingElse"; 

    MockitoTest mt = Mockito.mock(MockitoTest.class); 
    when(mt.getSomething()).thenReturn(something); 
    when(mt.getSomethingElse()).thenReturn(somethingElse); 

被嘲笑的定義是這樣的類:

public class MockitoTest { 

private final String something; 
private volatile String somethingElse; 

public MockitoTest(String theThing){ 
    something = theThing; 
} 

public String getSomething(){ 
    return something; 
} 

public String getSomethingElse(){ 
    return somethingElse; 
} 

@Override 
public final int hashCode() { 
    return something.hashCode(); 
} 

@Override 
public final boolean equals(Object o) { 
    if(!(o instanceof MockitoTest)) 
     return false; 
    return something.equals(((MockitoTest)o).something); 
} 

}

很清楚地看到,NPE從平等的未來()正在發生的事情,因爲構造函數是不是沒有設置運行和'某事'。

我的問題:爲什麼在第二次調用()時發生這種情況?有沒有辦法阻止equals方法被調用?難道我做錯了什麼?

注意:上面的例子被設計爲顯示錯誤發生。我試圖嘲笑的真正的課程是在一個不容易改變的第三方庫中。它不是輕而易舉地構建的,它需要一種在第三方包之外不可見的類型。正如上面的嘗試一樣,在我的測試包中寫下我的測試之餘還有什麼我可以做的來嘲笑它呢?

+0

您確定它是在「何時」發生錯誤?沒有無參數的構造函數,我不認爲變量會初始化,因此它們將爲空,但我不確定爲什麼你使用when()語句獲得NPE,因爲這不重要。 –

+0

哦,如果你正在模擬一個具體的對象,你可以嘗試一下spy()和doReturn(「asdfasd」)的Mockito語法。when(foo).doThing()。 –

回答

2

我很確定你的問題是equalshashCodefinal在你試圖模擬的類中。 Mockito需要重寫這些方法;所以這個類可能是無法調試的。

無論如何,嘲笑第三方課堂通常是一件壞事。您是否有可能重構您的應用程序,以便第三方課程被包裝?你的包裝只應該公開你需要使用的方法。當你編寫你的單元測試時,你可以模擬包裝。

+0

更多信息。我沒有意識到Mockito需要重寫equals和hashCode。在這種情況下,它必須默默地失敗,而其他問題也會出現。我最終在第三方包中聲明瞭測試,以便我可以訪問隱藏類型並構建有問題的對象。 感謝您的意見。 –

相關問題