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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 19:18:08  来源:igfitidea点击:

mockito: Is there a way of capturing the return value of stubbed method?

javamockito

提问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 answerset 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 Answerinstances and receive notfications each time the answermethod is called (which triggers the creation of a new Foo). So why not invent an ObservableAnswerclass:

像你看上去要观察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 */);