Как создать модульный тест для метода void с помощью try ... catch inside? - PullRequest
0 голосов
/ 05 июня 2019

создаю простой сервис например:

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 секунду.

customerMessagesService вернуть сообщение с рекламным текстом или выдать исключение, если это сообщение содержит недопустимый текст. Если customerMessagesService вернуть текст успеха - это отправить на spamCenterService, а если customerMessagesService сгенерировать исключение - это исключение только что зарегистрировано. Есть еще одна логика, которая может генерировать исключения между вызовами этих сервисов. Это исключение также регистрируется.

Теперь я хочу создать модульный тест для этого метода. Но я не понимаю, как проверить метод void с блоком try..catch.

Я создаю это:

public class MyServiceTest {

    private MyService myService;

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

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

Но это всегда успех, потому что метод процесса не генерирует исключения. Как я могу проверить этот метод?

EDIT

Я нашел одно решение, но я не уверен в этом.

открытый класс 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);
    }
}

И тест doIt() метод в MyServiceImpl.

1 Ответ

2 голосов
/ 05 июня 2019

Вкратце сделайте следующее:

  • Удалите создание объекта из вашего метода
  • Создайте макеты (с помощью, например, Mockito) и введите эти
  • , убедитесь, чтоmock были использованы, как и ожидалось

Конкретный пример ниже:

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

Обратите внимание, что вы также можете настроить mocks для выдачи определенных исключений или возврата определенных значений, чтобы вы могли проверить все возможныесценарии.

...