我有一个依赖于"now"Date对象的方法。
我想为它写一个单元测试。
所以我想注入一个假的固定的"现在"日期(让测试确定)。
我曾试图注入这样的间谍:
private ImagesSorter setServerWithSpyImageSorter(User user, List imagesAsInsertionOrder, Date fakeNowDate) throws IOException {
ImagesSorter imagesSorter = spy(new ImagesSorter());
when(imagesSorter.sortImages(imagesAsInsertionOrder, user)).thenReturn(imagesSorter.sortImages(imagesAsInsertionOrder, user, fakeNowDate));
//doReturn(imagesSorter.sortImages(imagesAsInsertionOrder, user, fakeNowDate)).when(imagesSorter).sortImages(imagesAsInsertionOrder, user);
server = VenueServerImplBuilder.create().withImagesSorter(imagesSorter).build();
server.init();
return imagesSorter;
}
但它不起作用。
1) 当我使用doReturn(imagesSorter.sortIm..
时,它得到了热切的评价。我不希望发生这种事。我能避免这种情况吗?
2) 当我注释掉doReturn(..
并使用when(imagesSorter.sor
时
我得到以下错误:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
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!
你会如何编码我想做的事情?
我认为您不需要Mockito在这里创建您的mock。由于ImageSorter
是一个具体的类,您不能制作一个真正的装饰器,但您可以制作类似于的东西
public class FixedDateImageSorter extends ImagesSorter {
final Date fixedDdate;
FixedDateImageSorter(Date fixedDate) {
this.fixedDdate = fixedDate;
}
public List sortImages(List s, User u) {
return sortImages(s, u, fixedDdate);
}
}
然后
private ImagesSorter setServerWithSpyImageSorter(User user, List imagesAsInsertionOrder, Date fakeNowDate) throws IOException {
ImagesSorter imagesSorter = new FixedDateImageSorter(fakeNowDate);
server = VenueServerImplBuilder.create().withImagesSorter(imagesSorter).build();
server.init();
return imagesSorter;
}
如果你真的想成为一名Mockito间谍,那么正如你所说,doReturn
会被热切地评估。因此,您需要使用doAnswer
来最近评估响应:
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.doAnswer;
...
final Date fakeNowDate = new Date();
final ImagesSorter imagesSorter = spy(new ImagesSorter());
doAnswer(new Answer<List>() {
public List answer(InvocationOnMock invocation) throws Throwable {
// Get the actual arguments
List arg1 = (List) invocation.getArguments()[0];
User arg2 = (User) invocation.getArguments()[1];
// Then call the 3-args method using fakeNowDate
return imagesSorter.sortImages(arg1, arg2, fakeNowDate);
}
}).when(imagesSorter).sortImages(any(List.class), any(User.class));
但我认为这不是最好的方法。
此语法不适用于间谍:
when(imagesSorter.sortImages(imagesAsInsertionOrder, user)).thenReturn(imagesSorter.sortImages(imagesAsInsertionOrder, user, fakeNowDate));
您需要使用以下结构:
doReturn(imagesSorter.sortImages(imagesAsInsertionOrder, user, fakeNowDate)).when(imagesSorter).sortImages(imagesAsInsertionOrder, user));
以下是相关文件(请参阅"监视真实物体的重要问题!"一节):http://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#13