如何使用mockito间谍重定向方法调用?

时间:2014-10-01 09:42:09

标签: java unit-testing junit mockito

我的方法依赖于"现在"日期对象。

我想为它写一个单元测试。

所以我想注射一个假的"现在"日期(确定测试)。

我试图像这样注射间谍:

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!

你会如何编码我想做的事情?

2 个答案:

答案 0 :(得分:1)

此语法对间谍不起作用:

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

答案 1 :(得分:0)

我认为你不需要Mockito在这里创建你的模拟。由于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));

但我不认为这是最好的方法。