[英]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.