[英]stubbing methods that manipulates parameters with mockito
我有以下情況:
class Worker {
public Integer somework() {
Integer k=0;
Helper h= new Helper();
h.change(k);
return k;
}
}
class Helper {
public void change(Integer k) {
//k = Some calcs
}
}
我正在為Worker
制作unitests,顯然我想要模仿Helper
類,這樣他的change
方法總是將1放入k
。
我的實際情況比較復雜,但這段代碼代表了問題。 感謝幫助。
我有一個定義如下的方法:
class Template{
public void process(Object rootMap, StringWriter out){
.......
}
}
我將向您展示如何更改/修改“out”(StringWriter)引用。
private final Template mocktTemplate = mock(Template.class);
doAnswer(new Answer<StringWriter>() {
public StringWriter answer(InvocationOnMock invocation)
throws Throwable {
Object[] args = invocation.getArguments();
if (args[1] instanceof StringWriter) {
StringWriter stringWriter = (StringWriter) args[1];
stringWriter.write("Email message");
}
return null;
}
}).when(this.mocktTemplate).process(anyObject(),any(StringWriter.class));
現在,當您確實進行實際調用時:
msgBodyTemplate.process(model, msgBodyWriter);
msgBodyWriter中Stringbuffer ref的值為“Email message”; 不論它早期的價值。
我認為doAnswer是處理void方法的最佳方法,其中方法操縱給定的參數。
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Mock mock = invocation.getMock();
return null;
}})
.when(mock).someMethod();
基本上,在獲得參數后,您可以進行任何您想要的修改。 有一篇博客文章解釋了一下。
至於@JB Nizet的觀點,是的,重構可測試性是件好事。 通常,重構以使代碼更易於測試會導致代碼更好地用於其他原因 - 分離關注點等等。 這並不總是可行的。 假設它不是你的代碼,或者你有其他要求讓它不管它(因為很多其他類依賴於它的方式)或者其他什么。
如果我明白你需要做什么,我想你可以用間諜來做:
Worker workerUnderTest = new Worker();
Worker spiedWorkerUT = spy(workerUnderTest);
Helper mockHelper = mock(Helper.class);
when(spiedWorkerUT.createHelper()).thenReturn(mockHelper);
Integer actual = spiedWorkerUT.someWork();
verify(mockHelper).change(0);
然后使用spiedWorkerUT而不是workerUnderTest來運行測試。
並不總是可以避免實例化你想要模擬的東西。 為此,有PowerMock 。
Helper mockHelper = mock(Helper.class);
whenNew(Helper.class).withNoArguments().thenReturn(mockHelper);
我會更改方法簽名,並將Helper
實例作為參數。 調用者將創建幫助程序並將其傳遞給somework
方法。 測試將通過模擬助手。
如果這是不可能的,至少調用一個受保護的工廠方法來創建幫助器,並在測試somework
方法時模擬這個工廠方法,以使它返回一個模擬助手:
class Worker {
public Integer somework(){
Integer k=0;
Helper h= createHelper();
h.change(k);
return k;
}
// this method may be mocked when testing somework, to return a mock helper.
protected Helper createHelper() {
return new Helper();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.