java mockito:有没有办法捕获存根方法的返回值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7254200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
mockito: Is there a way of capturing the return value of stubbed method?
提问by IttayD
If I mock a method to return a new instance of some object, how can I capture the returned instance?
如果我模拟一个方法来返回某个对象的新实例,我如何捕获返回的实例?
E.g.:
例如:
when(mock.someMethod(anyString())).thenAnswer(new Answer() {
Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return new Foo(args[0])
}
});
Obviously, I can have a field of type Foo and inside answer
set it to the new instance, but is there a nicer way? Something like ArgumentCaptor?
显然,我可以有一个 Foo 类型的字段并在里面answer
将它设置为新实例,但是有更好的方法吗?类似 ArgumentCaptor 的东西?
采纳答案by Andreas Dolk
Looks like you want to observethen Answer
instances and receive notfications each time the answer
method is called (which triggers the creation of a new Foo
). So why not invent an ObservableAnswer
class:
像你看上去要观察则Answer
实例和接收notfications每个时间answer
方法被调用(这将触发新的创造Foo
)。那么为什么不发明一个ObservableAnswer
类:
public abstract class ObservableAnswer implements Answer {
private Listener[] listeners; // to keep it very simple...
public ObservableAnswer(Listener...listeners) {
this.listeners = listeners;
}
@Override
public Object answer(InvocationOnMock invocation) {
Object answer = observedAnswer(invocation);
for (Listener listener:listeners) {
listener.send(answer);
}
return answer;
}
// we'll have to implement this method now
public abstract Object observedAnswer(InvocationOnMock invocation);
}
Intended use:
有可能的使用:
Listener[] myListenerns = getListeners(); // some magic (as usual)
when(mock.someMethod(anyString())).thenAnswer(new ObservableAnswer(myListeners) {
Object observedAnswer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return new Foo(args[0])
}
});
回答by Jeff Fairley
I wanted to do something similar, but with a spied object rather than a mock. Specifically, given a spied object, I want to capture the return value. Based on Andreas_D's answer, here's what I came up with.
我想做一些类似的事情,但是用一个间谍对象而不是一个模拟对象。具体来说,给定一个被监视的对象,我想捕获返回值。根据Andreas_D的回答,这就是我想出的。
public class ResultCaptor<T> implements Answer {
private T result = null;
public T getResult() {
return result;
}
@Override
public T answer(InvocationOnMock invocationOnMock) throws Throwable {
result = (T) invocationOnMock.callRealMethod();
return result;
}
}
Intended usage:
预期用途:
// spy our dao
final Dao spiedDao = spy(dao);
// instantiate a service that does some stuff, including a database find
final Service service = new Service(spiedDao);
// let's capture the return values from spiedDao.find()
final ResultCaptor<QueryResult> resultCaptor = new ResultCaptor<>();
doAnswer(resultCaptor).when(spiedDao).find(any(User.class), any(Query.class));
// execute once
service.run();
assertThat(resultCaptor.getResult()).isEqualTo(/* something */);
/// change conditions ///
// execute again
service.run();
assertThat(resultCaptor.getResult()).isEqualTo(/* something different */);