繁体   English   中英

如何使用try…catch在内部创建void方法的单元测试?

[英]How can I create unit test for void method with try…catch inside?

我创建简单的服务,例如:

public class MyService {

    public void process() {

        try {
            CustomerMessagesService customerMessagesService = new CustomerMessagesService();
            String message = customerMessagesService.getMessage();

            // another logic which can throw an exception                

            SpamCenterService spamCenterService = new SpamCenterService();
            spamCenterService.sendAdvertise(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

此服务每1秒从Scheduler调用一次。

customerMessagesService返回带有广告文本的消息,如果此消息包含非法文本,则引发异常。 如果customerMessagesService返回成功文本-发送给spamCenterService ,并且customerMessagesService引发异常-则记录该异常。 还有另一种逻辑可以在这些服务的调用之间引发异常。 该异常也会记录。

现在,我想为此方法创建一个单元测试 但是我不明白如何用try..catch块测试void方法。

我创建这个:

public class MyServiceTest {

    private MyService myService;

    @Before
    public void setUp() {
        myService = new MyService();
    }

    @Test
    public void process() {
        myService.process();
    }
} 

但这总是成功的,因为处理方法不会引发异常。 如何测试此方法?

编辑

我找到了一种解决方案,但我不确定。

公共类MyServiceImpl实现MyService {

    public void process() {
        try {
           doIt();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doIt() throws Exception {
      CustomerMessagesService customerMessagesService = new CustomerMessagesService();
            String message = customerMessagesService.getMessage();

            // another logic which can throw an exception                

            SpamCenterService spamCenterService = new SpamCenterService();
            spamCenterService.sendAdvertise(message);
    }
}

然后在MyServiceImpl测试doIt()方法。

简而言之,请执行以下操作:

  • 将对象创建移出方法
  • 创建模拟(例如使用Mockito)并将其注入
  • 验证模拟是否按预期使用

下面是一个具体示例:

public class MyService {

    private CustomerMessagesService customerMessagesService;
    private SpamCenterService spamCenterService;

    //inject dependencies
    public MyService(CustomerMessagesService customerMessagesService, SpamCenterService spamCenterService) {
        this.customerMessagesService = customerMessagesService;
        this.spamCenterService = spamCenterService;
    }

    public void process() {
        try {
            String message = customerMessagesService.getMessage();

            // another logic which can throw an exception

            spamCenterService.sendAdvertise(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


public class MyServiceTest {

    private MyService myService;
    // mock dependencies with Mockito
    private CustomerMessagesService customerMessagesService = Mockito.mock(CustomerMessagesService.class);
    private SpamCenterService spamCenterService = Mockito.mock(SpamCenterService.class);

    @Before
    public void setUp() {
        myService = new MyService(customerMessagesService, spamCenterService);
    }

    @Test
    public void process() {
        myService.process();

        Mockito.verify(customerMessagesService).getMessage();
        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
        Mockito.verify(spamCenterService).sendAdvertise(messageCaptor.capture());
        assertThat(messageCaptor.getValue(), is(nullValue()));
    }

    @Test
    public void processWithSpecificCustomerMessageServiceBehaviour() {
        Mockito.given(customerMessagesService.getMessage()).willReturn("expectedString");

        myService.process();

        ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
        Mockito.verify(spamCenterService).sendAdvertise(messageCaptor.capture());
        assertThat(messageCaptor.getValue(), is("expectedString"));
    }

    @Test
    public void processCatchExceptions() {
        Mockito.given(customerMessagesService.getMessage()).willThrow(new Exception("Bad message"));

        myService.process();

        // if exception is thrown then the code should not reach spamCenterService.sendAdvertise()
        Mockito.verify(spamCenterService, Mockito.never()).sendAdvertise(Mockito.anyString());
    }
} 

请注意,您还可以设置模拟以引发特定的异常或返回特定的值,以便可以测试所有可能的方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM