Mockito使用不同的Class参数调用相同的方法 [英] Mockito calling same method with different Class paramter

查看:329
本文介绍了Mockito使用不同的Class参数调用相同的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务,其方法看起来像这样-

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:

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

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

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

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

使用

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

但是它不起作用,因为Customer对象是在handleUser方法内部创建的,因此两个实例都不同,并且不会引发我在Test中设置的Exception.

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.

类似于,

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

同样,由于两个Customer实例都不相同,因此按照测试设置,它不会引发异常.

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?

推荐答案

这里有两个想法:

  • 验证这些非交互是否真的强制性?换句话说:完全验证该方面真的有帮助吗?
  • 那是什么情况:为什么要关注这种特殊情况?
  • 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?

换句话说:

  • 预期调用创建模拟规范
  • 改为在模拟游戏中使用verifyNoMoreInteractions(请参见此处以供进一步阅读).
  • create a mocking spec for the expected calls
  • use verifyNoMoreInteractions on your mock instead (see here for further reading).

SO:指定所有预期的呼叫,并确认未发生任何事情.为您提供相同的结果,并且易于记录且易于理解.

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.

感谢@GhostCat的答案,只想添加这两行代码,我就按照您的建议验证了此测试方案-

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

这篇关于Mockito使用不同的Class参数调用相同的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆