Mockito用不同的Class参数调用相同的方法

时间:2017-09-11 06:14:17

标签: unit-testing testing mocking mockito

我正在提供一种服务,其方法看起来有点像这样 -

class ServiceClass {

    @Inject
    EventService event;

    public void handleUser(User user) throws ServiceClassException {
        Customer customer = userToCustomer(user);
        CustomerDetail detail = userToCustomerDetail(user);

        try {
            Response response1 = event.generateEvent(customer);
        } catch(Exception e) {
            throw new ServiceClassException();
        }

        try {
            Response response2 = event.generateEvent(detail);
        } catch(Exception e) {
            throw new ServiceClassException();
        } 
    }

    private Customer userToCustomer(User user) {
        // Some logic
    }

    private CustomerDetail userToCustomerDetail(User user) {
        // Some logic
    }
}

现在在编写测试时,我想检查异常处理。这就是我的测试用例的样子。

class ServiceClassTest {

    @InjectMocks
    ServiceClass service;

    @Mock
    EventService event;

    @Before
    public void setUp() {
        User user = new User();
        user.setValue("fsfw");
    }

    @Test
    public void handleUserThrowsException() throws Exception {
        Mockito.when(event.generateEvent(Mockito.any(Customer.class))).thenThrow(new RuntimeException());

        try {
            Response response1 = service.handleUser(user);
        } catch(ServiceClassException e) {}

        Mockito.verify(event, Mockito.never()).generateEvent(Mockito.any(CustomerDetail.class));
    }
}

以上测试用例失败,显示消息从不想要在这里:,但在此处调用

由于两者都是any类型,因此无法区分不应执行哪种方法。

我尝试了不同的变化,例如更换线路 - Mockito.when(event.generateEvent(Mockito.any(Customer.class))).thenThrow(new RuntimeException());

Mockito.when(event.generateEvent(Customer.class)).thenThrow(new RuntimeException());

但它不起作用,因为Customer对象是在handleUser方法中创建的东西,因此两个实例都不同,并且它没有抛出我在测试中设置的异常。

类似
Customer customer = new Customer;
customer.setValue("fsfw");
Mockito.when(event.generateEvent(customer)).thenThrow(new RuntimeException());

同样,由于两个Customer实例都不同,因此根据测试设置,它不会抛出异常。

你们有人可以建议如何测试这个吗?编写像这样的测试用例有效,但我不知道这是否是正确的方法 -

@Test
public void handleUserThrowsException() throws Exception {
    Mockito.when(event.generateEvent(Mockito.any(Customer.class))).thenThrow(new RuntimeException());

    try {
        Response response1 = service.handleUser(user);
    } catch(ServiceClassException e) {}

    Mockito.verify(event, Mockito.never()).generateEvent(CustomerDetail.class);
}

请让我知道进行此类测试的正确方法?

1 个答案:

答案 0 :(得分:1)

这里有两个想法:

  • 验证这些非互动是真的强制性吗?换句话说:验证那个方面真的很有帮助吗?
  • 并且在这种情况下:为什么要专注于特殊案例?

换句话说:

  • 预期的调用
  • 创建一个模拟规范
  • 在您的模拟上使用verifyNoMoreInteractions(请参阅here进一步阅读)。

SO:指定所有预期的来电,并确认发生。给你相同的结果,易于记录,易于理解。

感谢@GhostCat的回答,只想添加这两行代码,我用它来验证这个测试场景 -

    @Test
    public void handleUserThrowsException() throws Exception {
        Mockito.when(event.generateEvent(Mockito.any())).thenThrow(new RuntimeException());

        try {
            Response response1 = service.handleUser(user);
        } catch(ServiceClassException e) {}

        Mockito.verify(event, Mockito.times(1)).generateEvent(Mockito.any());
        Mockito.verifyNoMoreInteractions(event);
    }