Mockito - thenReturn总是返回null对象

时间:2014-10-31 17:52:22

标签: java null mockito

我试图实现Mockito来测试一个特定的方法但是.thenReturn(...)似乎总是返回一个null对象而不是我想要的:

CUT:

public class TestClassFacade {

  // injected via Spring
  private InterfaceBP bpService;

  public void setBpService(InterfaceBP bpService) {

      this.bpService = bpService;
  }

  public TestVO getTestData(String testString) throws Exception {

    BPRequestVO bpRequestVO = new BPRequestVO();

    bpRequestVO.setGroupNumber(testString) ;
    bpRequestVO.setProductType("ALL") ;           
    bpRequestVO.setProfileType("Required - TEST") ;

    IBPServiceResponse serviceResponse = bpService.getProduct(bpRequestVO);  //PROBLEM

    if (serviceResponse.getMessage().equalsIgnoreCase("BOB")) {

        throw new Exception();

    } else {

        TestVO testVO = new TestVO();
    }

    return testVO;
  }

}

Spring配置:

<bean id="testClass" class="com.foo.TestClassFacade">

   <property name="bpService" ref="bpService" />

</bean>

<bean id="bpService" class="class.cloud.BPService" />

Mockito测试方法:

@RunWith(MockitoJUnitRunner.class)
public class BaseTest {

    @Mock BPService mockBPService;
    @InjectMocks TestClassFacade mockTestClassFacade;

    private String testString = null;
    private BPRequestVO someBPRequestVO = new BPRequestVO();
    private IBPServiceResponse invalidServiceResponse = new BPServiceResponse();

    @Test (expected = Exception.class)
    public void getBPData_bobStatusCode_shouldThrowException() throws Exception {

        invalidServiceResponse.setMessage("BOB");

        someBPRequestVO.setGroupNumber(null);
        someBPRequestVO.setProductType("ALL");
        someBPRequestVO.setProfileType("Required - TEST");

        System.out.println("1: " + someBPRequestVO.getGroupNumber());
        System.out.println("2: " + someBPRequestVO.getProductType());
        System.out.println("3: " + someBPRequestVO.getProfileType());
        System.out.println("4: " + someBPRequestVO.getEffectiveDate());

        when(mockBPService.getProduct(someBPRequestVO)).thenReturn(invalidServiceResponse);

        mockTestClassFacade.getTestData(testString);

        verify(mockBPService).getProduct(someBPRequestVO);
    }
}

系统输出:

1: null
2: ALL
3: Required - TEST
4: null

这里发生的事情是,当我运行测试时,serviceResponse对象在CUT标记为// PROBLEM的行上为空。我的愿望是用我的&#34; invalidServiceResponse&#34;填充该对象。来自我的测试方法的对象。从我的System.out.println的输出来看,我的bpRequestVO似乎与我的someBPRequestVO在内容中匹配。

有人可以告诉我我在这里失踪了吗?

谢谢你的时间!

5 个答案:

答案 0 :(得分:9)

您与when()一起使用的BPRequestVO实例与getTestData()中使用的实例不同。
除非您覆盖equals(),否则它们将无法匹配。

如果覆盖equals(),则不需要编写自定义匹配器。请注意Mockito documentation中的以下内容:

  

&#34;自定义参数匹配器可以降低测试的可读性。有时为传递给模拟的参数实现equals()会更好(Mockito自然地使用equals()进行参数匹配)。这可以使测试更清洁。&#34;

答案 1 :(得分:5)

问题在于您使用when()

您提交对构造实例的引用;因此,只有传递给方法的参数相同的引用时,模拟才会返回您想要的内容。

你想要的是一个论证匹配器;类似的东西:

when(mockBPService.getProduct(argThatMatches(someBPRequestVO))
    .thenReturn(whatYouWant);

当然,它要求您编写参数匹配器!

请注意,内置匹配器可以执行您想要的操作:

when(mockBPService.getProduct(eq(someBPRequestVO))).thenReturn(whatYouWant);

此匹配器当然要求您的BPRequestVO类实现equals()(以及hashCode())!

答案 2 :(得分:3)

您可以使用“any(YourObject.class)”创建一个模拟参数,而不是在BPRequestVO类中创建一个equals方法:

when(mockBPService.getProduct(any(BPRequestVO.class))).thenReturn(invalidServiceResponse);

答案 3 :(得分:0)

用于模拟的BPRequestVO对象实例与junit执行时使用的实例不同。

最好的方法是在模拟时配置对象的任何实例

$flaglightgallery.on('onAfterAppendSubHtml.lg', function() { 
   // things you want to happen after triggering light gallery.
});

可以用

更新
when(mockBPService.getProduct(someBPRequestVO)).thenReturn(invalidServiceResponse);

答案 4 :(得分:0)

我的问题是模拟服务被定义为 final。