Mockito calling same method with different Class paramter

你说的曾经没有我的故事 提交于 2019-12-24 12:14:02

问题


I am having a service whose method looks somewhat like this -

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
    }
}

Now while writing the test, I wanna check the exception handling. This is how my test case looks like.

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

The above test case is failing with the message Never wanted here:, But invoked here:

Since both are of type any it is unable to differentiate between which method should not be executed.

I have tried different variations like replacing the line - Mockito.when(event.generateEvent(Mockito.any(Customer.class))).thenThrow(new RuntimeException());

with

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

But it is not working because the Customer object is something which is created inside handleUser method and so both the instance are different and it is not throwing Exception which I setup in the Test.

Similar with,

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

Again since both the Customer instance are different it is not throwing Exception as it is suppose to according to the Test setup.

Can any of you suggest how to test this one? Writing a test case like this works, but I don't know if this is the correct way to do it or not -

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

Please let me know the correct way to do this kind of testing?


回答1:


Two thoughts here:

  • is it really mandatory for you to verify those non-interactions? In other words: is it really helpful to verify that aspect at all?
  • and when that is the case: why focus on that special case?

In other words:

  • create a mocking spec for the expected calls
  • use verifyNoMoreInteractions on your mock instead (see here for further reading).

SO: specify all expected calls, and verify that nothing else happened. Gives you the same result, and is easy to write down, and easy to comprehend.

Thanks @GhostCat for the answer, just want to add these two lines of code which I used to verify this test scenario as suggested by you -

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


来源:https://stackoverflow.com/questions/46149263/mockito-calling-same-method-with-different-class-paramter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!