对Mockito Mock的链接方法调用返回Null

时间:2019-07-08 22:37:39

标签: java unit-testing mocking mockito method-chaining

我后面有一个@Component,其中有一个注入的对象,该对象通过调用链方法来获取某物,例如

@Component
public class MyInterceptor implements ClientHttpRequestInterceptor {

  @Autowired
  public MyProducer producer;

  @Override
  public ClientHttpResponse intercept(…) throws IOException {
    String val = producer.getProducer().getSomeVal(/*parameters*/); // LINE (1)
  }

}

我的测试课是:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyInterceptor.class, MyProducer.class } )

public class MyInterceptorTest {

  private RestTemplate restTemplate = new RestTemplate();
  private MockRestSErviceServer mockServer;

  @Rule
  public MockitoRule rule = MockitoJUnit.rule();

  @Mock
  public MyProducer producer;

  @InjectMocks
  private MyInterceptor interceptor;

  @Before
  public void init() {
    //MockitoAnnotation.initMocks(this);
    producer = Mockito.mock(MyProducer.class, Mockito.RETURNS_DEEP_STUBS);
    // adding interceptor to RestTemplate
    mockServer = MockRestServiceServer.createServer(restTemplate);

    when(producer.getProducer().getSomeVal(null, null)).thenReturn("SomeValue");

  }

  @Test
  public void myTestMethod() {
    mockServer.expect(requestTo(/*some dummy URL*/)
      .andExpect(method(HttpMethod.GET))
      .andExcept(/*some header stuff omitted from MyInterceptor */)
      .andRespond(withSuccess(/*…*/));

    // This is going to trigger the Interceptor being invoked
    restTemplate.getForEntity("some dummy URL", String.class); // LINE (2)

    mockServer.verify();
  }
}

当测试执行LINE(2)并调用拦截器时,在LINE(1)中我得到一个空指针异常。

我当时的假设是,通过在模拟对象上启用深度存根,我将能够进行链式调用并获得期望值,例如producer.getProducer().getSomeVal(),但事实并非如此。

您知道我如何使它按预期工作吗?

P.S。我尝试了添加MockitoAnnotation.initMocks()并摆脱@Rule或在测试类中仅删除@Autowired MyInterceptor的变化,这导致MyProducer完全被嘲笑,但似乎没有任何作用。

注意,MyProducer不能被修改,因为它来自另一个项目。

1 个答案:

答案 0 :(得分:0)

您已经嘲笑了MyProducer类,但是没有为when提供producer.getProducer()

因此,当代码调用producer.getProducer()时,它将返回默认的模拟值,该值为null。

您可以尝试几种不同的方法:

when(producer.getProducer()).thenReturn(producer);

我不确定这是否行得通-可能。

否则,您可能可以编写实现/扩展getProducer()返回值的本地测试类,当将正确的参数传递给getSomeVal()时,该类又返回适当的测试值。