如何使用 mockito 来模拟构建者

2022-09-01 03:28:26

我有一个构建器:

class Builder{
     private String name;
     private String address;
     public Builder setName(String name){
         this.name = name;
         return this;
    }
     public Builder setAddress(String address){
         this.address = address;
         return this;
    }

}

在 mockito 中嘲笑构建器将为每个方法提供 null。那么有没有一种简单的方法可以让构建器在每次函数调用时返回自身,而无需使用 来模拟每个函数本身。when().thenReturn


答案 1

使用RETURN_DEEP_STUBS的问题在于,每次调用方法时都会得到不同的模拟。从您的问题中,我认为您希望使用默认的Answer,该答案实际上返回调用它的模拟,对于具有正确返回类型的每个方法。这可能如下所示。请注意,我还没有对此进行测试,因此它可能包含拼写错误,但我希望在任何情况下意图都很清楚。

import static org.mockito.Mockito.RETURNS_DEFAULTS;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class SelfReturningAnswer implements Answer<Object> {

    public Object answer(InvocationOnMock invocation) throws Throwable {
        Object mock = invocation.getMock();
        if(invocation.getMethod().getReturnType().isInstance(mock)){
            return mock;
        }
        return RETURNS_DEFAULTS.answer(invocation);
    }
}

然后,在创建模拟时,将其指定为默认答案。这将使您的模拟从它所能的每个方法返回;但是当您调用一个返回类型为 mock 错误的方法时,它的行为将像普通 mock 一样。

像这样创建你的模拟

Builder mockBuilder = mock( Builder.class, new SelfReturningAnswer());

或者为这个类创建一个常量,并编写类似的东西

@Mock(answer = SELF_RETURNING) private Builder mockBuilder;

希望有所帮助。


答案 2

从Mockito 2.0(测试版)开始,RETURNS_SELF有一个新的默认答案,其行为与David Wallace的答案几乎相同。Mockito文档中的示例:

@Test
public void use_full_builder_with_terminating_method() {
    HttpBuilder builder = mock(HttpBuilder.class, RETURNS_SELF);
    HttpRequesterWithHeaders requester = new HttpRequesterWithHeaders(builder);
    String response = "StatusCode: 200";

    when(builder.request()).thenReturn(response);

    assertThat(requester.request("URI")).isEqualTo(response);
}

请注意,它同时出现在类和枚举中,因此它也与语法兼容。MockitoAnswers@Mock(answer = RETURNS_SELF)


推荐