Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对Mockito Mock的链接方法调用返回Null_Java_Unit Testing_Mocking_Mockito_Method Chaining - Fatal编程技术网

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

Java 对Mockito Mock的链接方法调用返回Null,java,unit-testing,mocking,mockito,method-chaining,Java,Unit Testing,Mocking,Mockito,Method Chaining,我有一个带有注入对象的@Component,它通过链式方法调用来获取一些东西,例如 @Component public class MyInterceptor implements ClientHttpRequestInterceptor { @Autowired public MyProducer producer; @Override public ClientHttpResponse intercept(…) throws IOException { Strin

我有一个带有注入对象的@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();
  }
}
当测试执行第2行并调用拦截器时,在第1行我得到一个空指针异常

我的假设是,通过在模拟上启用深度存根,我将能够进行链式调用并获得预期值,例如producer.getProducer.getSomeVal,但事实似乎并非如此

你知道我怎样才能让它按预期工作吗

另外,我尝试了添加MockitoAnnotation.initMocks和在测试类中去掉@Rule,或者只去掉@Autowired MyInterceptor的不同变体,这使得MyProducer根本不被模仿,但似乎没有任何效果

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

您模拟了MyProducer类,但没有为producer.getProducer提供when

因此,当代码调用producer.getProducer时,它将返回默认的模拟值,即null

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

when(producer.getProducer()).thenReturn(producer);
我不确定这是否行得通——也许行


否则,您可以编写一个本地测试类,实现/扩展getProducer返回的任何内容,当正确的参数传递给getSomeVal时,该类将返回相应的测试值。

MyInterceptorintercept调用producer.getProducer.getSomeVal,我认为启用带有返回\u DEEP\u存根的方法链接可以解决这个问题。现在,正如你所说的,我需要补充什么才能使这项工作顺利进行?我不能执行doReturn/*某些生产者*/。whenproducer.getProducer然后下一行whenproducer.getSomeValnull,null.thenReturnSomeValue会抱怨返回类型错误。即使我执行producer=doReturn/*某些生产者*/。whenproducer.getProducer,whenfromProducer.getSomeVal/*…*/。thenReturnSomeValue,fromProducer仍然为空。我甚至尝试了producer=doAnswernew Answer{/*…*/}中的某个对象。whenproducer.getProducer具有相同的结果。编辑以提供潜在的解决方案。调用producer.getProducer不会返回MyProducer,但正如我在前面的评论中提到的,它返回另一个我称为getSomeVal的对象。不管怎样,我尝试了建议的路线,它仍然抛出NPE。我所做的是,和你的一样,我去掉了producer=Mockito.mockMyProducer.class,Mockito.RETURNS\u DEEP\u STUBS;总之,应用程序在较低的环境中为producer.getProducer提供了一个静态变量,我用它返回,然后用它调用getSomeVal,这就成功了。你能把intercept的实现分成两行吗?第一个是producer.getProducer,第二个是.getSomeVal调用?然后使用调试器,查看哪一个为您提供空指针异常。@Jason,这将是producer.getProducer,它为空。