简体   繁体   English

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

[英]Chaining Method Calls to a Mockito Mock Returns Null

I have a following @Component with an injected object that makes a chain method call to get something, eg 我有一个下面的@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)
  }

}

And my test class is: 我的测试课是:

@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();
  }
}

When the test executes LINE (2), and it invokes the interceptor, in LINE (1) I get a null pointer exception. 当测试执行LINE(2)并调用拦截器时,在LINE(1)中,我得到一个空指针异常。

I was under the assumption that by enabling deep stubbing on a mock, I would be able to make a chain call and get an expected value, eg producer.getProducer().getSomeVal() , but it doesn't seem to be the case. 我当时的假设是,通过对某个模拟启用深度存根,我将能够进行链调用并获得期望的值,例如producer.getProducer().getSomeVal() ,但事实并非如此。 。

Do you know how I can get this working as expected? 您知道我如何使它按预期工作吗?

PS I have tried different variation of adding MockitoAnnotation.initMocks() and getting rid of @Rule , or just @Autowired MyInterceptor in the test class which in this causes MyProducer not to be mocked at all, but nothing seems to work. PS我尝试了添加MockitoAnnotation.initMocks()并摆脱@Rule或在测试类中仅MyInterceptor @Autowired MyInterceptor不同变体,这在所有情况下都不会嘲笑MyProducer ,但似乎没有任何效果。

Note, MyProducer cannot be modified as it is from another project. 注意,不能修改MyProducer因为它来自另一个项目。

You've mocked the MyProducer class, but you haven't provided a when for producer.getProducer() . 你嘲笑MyProducer类,但您没有提供一个whenproducer.getProducer()

So, when the code calls producer.getProducer() it will return the default mock value, which is null. 因此,当代码调用producer.getProducer() ,它将返回默认的模拟值,该值为null。

You could try a couple of different approaches: 您可以尝试几种不同的方法:

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

I'm not sure if that will work - it might. 我不确定这是否行得通-可能会。

Otherwise, you may be able to write a local test class that implements/extends whatever getProducer() returns, which in turn returns the appropriate test value when the correct parameters are passed to getSomeVal() . 否则,您可能可以编写实现/扩展getProducer()返回值的本地测试类,当将正确的参数传递给getSomeVal()getSomeVal()又返回适当的测试值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM