2017-09-26 187 views
2

我正在編寫一個測試,以驗證我的類在接收來自SOAP服務的不同響應時的行爲。 我使用JAXB,所以我的迴應包含JaxbElements,對於他們來說,我需要寫一個假,這樣的:Mockito模擬方法內的對象

JAXBElement<String> mock1 = mock(JAXBElement.class); 
when(mock1.getValue()).thenReturn("a StringValue"); 
when(result.getSomeStringValue()).thenReturn(mock1); 

JAXBElement<Integer> mock2 = mock(JAXBElement.class); 

when(mock2.getValue()).thenReturn(new Integer(2)); 
when(result.getSomeIntValue()).thenReturn(mock2); 
... <continue> 

什麼,我想這樣做,是refactorize這段代碼的方式:

when(result.getSomeStringValue()) 
    .thenReturn(mockWithValue(JAXBElement.class, "a StringValue"); 

when(result.getSomeIntValue()) 
    .thenReturn(mockWithValue(JAXBElement.class, 2)); 

,並定義一個方法:

private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) { 
    JAXBElement<T> mock = mock(jaxbElementClass); 
    when(mock.getValue()).thenReturn(value); 
    return mock; 
} 

當我執行的代碼重構一切正常了。 不幸的是,當我重構之後執行所述的代碼,我收到此錯誤:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here: 
-> at com.mypackage.ResultConverterTest.shouldConvertASuccessfulResponseWithAllTheElements(ResultConverterTest.java:126) 

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
when(mock.isOk()).thenReturn(true); 
when(mock.isOk()).thenThrow(exception); 
doThrow(exception).when(mock).someVoidMethod(); 
Hints: 
    1. missing thenReturn() 
    2. you are trying to stub a final method, you naughty developer! 
    3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed 

其中線126是mockWithValue方法的第一次調用。

所以問題是:有沒有一種方法可以重複使用相同的代碼來創建許多具有類似行爲的模擬?

+0

由於JAXB生成類是沒有任何商業行爲簡單的DTO你不應該嘲笑他們...... –

+0

因爲構建它們需要其他對象(Qname名稱,類 declaredType,Class scope,T值),並且它的可讀性會下降。無論如何,我可以做到這一點,但我遇到了這個例外,我想了解它。 – marco

回答

1

您不應該在創建響應時進行模擬。

讓我解釋一下,這個代碼

private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) { 
    JAXBElement<T> mock = mock(jaxbElementClass); 
    when(mock.getValue()).thenReturn(value); 
    return mock; 
} 

你嘲笑JAXBElement<T> mock = mock(jaxbElementClass),然後你在return響應使用此方法完成。

您應該先分別創建這些響應,然後在return內使用它們。

String stringResponse=mockWithValue(JAXBElement.class, "a StringValue"); 
when(result.getSomeStringValue()).thenReturn(stringResponse); 

試試這個,它會工作。

+1

我仍然不明白爲什麼,但是,它的工作原理!謝謝! – marco

+0

另請參閱提示#3 3:如果完成 –

2

當涉及到一些額外的仿製藥的參與,同時嘲諷這是更好地去爲doReturn()..when()語法:

doReturn(mockWithValue(JAXBElement.class, "a StringValue")) 
     .when(result).getSomeStringValue(); 

    doReturn(mockWithValue(JAXBElement.class, 2)) 
     .when(result).getSomeIntegerValue(); 

private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) { 
     JAXBElement<T> mock = mock(jaxbElementClass); 
     doReturn(value).when(mock).getValue(); 
     return mock; 
    } 
+0

這就是我正在尋找的內容,那麼您在「返回」指令之前將另一個模擬內容的行爲存起來,謝謝! – marco