如何根据参数属性在Mockito中返回不同的值?

Roe*_*rel 16 java mockito

我测试的类接收客户端包装器:

测试类(snippest)

private ClientWrapper cw
public Tested(ClientWrapper cw) {
    this.cw = cw;
}

public String get(Request request) {
    return cw.getClient().get(request);
}
Run Code Online (Sandbox Code Playgroud)

测试初始化​​:

ClientWrapper cw = Mockito.mock(ClientWrapper.class);
Client client = Mockito.mock(Client.class);
Mockito.when(cw.getClient()).thenReturn(client);
//Here is where I want to alternate the return value:
Mockito.when(client.get(Mockito.any(Request.class))).thenReturn("100");
Run Code Online (Sandbox Code Playgroud)

在exmaple中我总是返回"100",但Request有一个属性id,我想client.get(Request)根据值返回不同的request.getId()值.

我该怎么做?

Ada*_*ion 26

您可以使用Mockito的答案,而不是:

Mockito.when(client.get(Mockito.any(Request.class))).thenReturn("100");
Run Code Online (Sandbox Code Playgroud)

写:

Mockito.when(client.get(Mockito.any(Request.class)))
 .thenAnswer(new Answer() {
   Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return "called with arguments: " + args;
   }
});
Run Code Online (Sandbox Code Playgroud)


Joh*_*ery 7

你可以创建一个ArgumentMatcher让你匹配Requestby id.

所以参数匹配器就是这样的:

import org.mockito.ArgumentMatcher;

public class IsRequestWithId implements ArgumentMatcher<Request> {
    private final int id;

    public IsRequestWithId(int id) {
        this.id = id;
    }

    @Override
    public boolean matches(Object arg) {
        Request request = (Request)arg;
        return id == request.getId();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它像:

Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(1)))).thenReturn("100");
Mockito.when(client.get(Mockito.argThat(new IsRequestWithId(2)))).thenReturn("200");
Run Code Online (Sandbox Code Playgroud)

否则使用一个Answer也可以工作,但使用一个ArgumentMatcher让你保持代码更"声明".


mag*_*ter 6

为了做到正确并用最少的代码,您必须使用ArgumentMatcherlambda表达式,并且不要忘记ArgumentMatcherlambda中的filter成员进行null检查(特别是如果您有多个具有相同的模拟ArgumentMatcher)。

自定义参数匹配器:

private ArgumentMatcher<Request> matchRequestId(final String target) {
    return request -> request != null &&
            target.equals(request.getId());
}
Run Code Online (Sandbox Code Playgroud)

用法:

 given(client.get(argThat(matchRequestId("1")))).willReturn("100");
 given(client.get(argThat(matchRequestId("2")))).willReturn("200");
Run Code Online (Sandbox Code Playgroud)