如何用mockito模拟一个构建器

我有一个建设者:

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每个函数本身。

您可以使用RETURN_DEEP_STUBS来模拟链接API。

如果您知道将调用构建器的确切顺序,以下是如何使用它的示例:

 Builder b = Mockito.mock(Builder.class, RETURNS_DEEP_STUBS); when(b.setName("a name").setAddress("an address")).thenReturn(b); assert b.setName("a name").setAddress("an address") == b; // this passes 

不幸的是,这不会给你一个模拟“所有各种构建器方法”的通用方法,以便它们总是返回这个,看到另一个答案就是你需要它。

使用RETURN_DEEP_STUBS的问题在于,每次调用方法时都会得到不同的模拟。 我想从你的问题中你想要使用一个默认的Answer,它实际上返回了调用它的mock,对于每个具有正确返回类型的方法。 这可能类似于以下内容。 请注意,我没有对此进行测试,因此可能包含错别字,但我希望无论如何都要明确其用意。

 import static org.mockito.Mockito.RETURNS_DEFAULTS; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class SelfReturningAnswer implements Answer{ public Object answer(InvocationOnMock invocation) throws Throwable { Object mock = invocation.getMock(); if( invocation.getMethod().getReturnType().isInstance( mock )){ return mock; } else{ return RETURNS_DEFAULTS.answer(invocation); } } } 

然后,在创建模拟时,将其指定为默认答案。 这将使你的模拟返回它自己的每个方法; 但是当你调用一个返回类型错误的方法时,它会表现得像普通的模拟。

像这样创建你的模拟

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

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

 @Mock( answer = SELF_RETURNING ) private Builder mockBuilder; 

希望有所帮助。

从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); } 

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