Модульные тесты утверждают против Mockito.verify () - PullRequest
0 голосов
/ 21 января 2019

Возиться с Mockito для реализации модульных тестов моих сервисов, но по какой-то причине я не могу получить это через свой толстый череп. Мои тесты проходят, но я не убежден, что я делаю это правильно.

Вот пример, где я тестирую метод count (). Метод просто перенаправляет вызов в свой репозиторий, и я не хочу проверять, что только это и ничего больше не происходит. Вот что у меня есть:

@RunWith(MockitoJUnitRunner.class)
public class PersonServiceImplTest {

    @Mock
    private PersonRepository personRepository;

    @InjectMocks
    private PersonServiceImpl personService;

    @Test
    public void testCount() {

        when(personRepository.count()).thenReturn(2L);

        long count = personService.count();

        assertEquals(2L, count);

        verify(personRepository).count();
    }
}

Мой тест пройден, но у меня есть несколько вопросов.

  1. Нужны ли assertEquals? насколько я понимаю, все, что я положил в качестве ожидаемого результата заглушки метода (.thenReturn (value ..)), ВСЕГДА будет возвращаемым значением. Или это может быть что-то еще в этом сценарии?

  2. Нужно ли проверять? Я чувствую, что я делаю, потому что я хочу убедиться, что personRepository.count () действительно был вызван Или это избыточно, когда у меня также есть assertEquals ()?

  3. Нужны ли оба assertEquals и проверить?

  4. И, наконец, я делаю это правильно:)

Спасибо

Ответы [ 3 ]

0 голосов
/ 21 января 2019

Лучше вводить PersonRepository через конструктор, чем @InjectMocks. Это также устраняет необходимость в конкретном бегуне (или, позже, в вашем тестировании, включая Spring для низкоуровневых тестов).

Вы используете Mockito правильно , но не оптимально. Вам нужен assertEquals, потому что вы проверяете, что служба возвращает то же значение, которое вы предоставляете из репозитория. verify...count не является необходимым, поскольку он подразумевается путем проверки, что соответствующее значение было возвращено. Вы можете улучшить это, возвращая случайное число вместо 2.

Также проверьте, действительно ли стоит обернуть count() в другой объект или вы просто добавляете ненужные слои.

Наконец, вы можете рассмотреть вопрос Спок ; это основанный на Groovy тестовый язык поверх JUnit, который обеспечивает чистый и мощный фиктивный язык.

0 голосов
/ 21 января 2019

В заказе:

  1. Требуется ли assertEquals(): Зависит от.Есть ли что-нибудь, что было сделано с результатом personRepository.count() в personService перед его возвращением, что может изменить его значение?Если ответ «определенно нет», то вам может не потребоваться assertEquals() - но если есть вероятность, что что-то может пойти не так, то assertEquals() позаботится о том, чтобы это не произошло.

  2. Нужно ли вам verify(): Это зависит.Есть ли вероятность, что personRepository.count() не позвонили?Или что он вызывался более одного раза (verify() по умолчанию ожидает, что его аргумент будет вызван ровно один раз)?Если нет, то вам это может не понадобиться.

  3. Вам нужны оба: Это зависит (замечая образец?).Смотри выше: они делают разные вещи.Есть много случаев, когда вы хотите, чтобы обе вещи были проверены: 1. что верный результат возвращается, и 2. что результат возвращается, выполняя действия, которые вы ожидаете сделать.

  4. Вы делаете это правильно: Ну ... Это зависит.Выглядит ли personRepository.count() как

    public int count() {
        return this.personService.count();
    }
    

Если это так, вам, вероятно, не нужно много тестировать его вообще.Если вы настаиваете на проведении теста, пропуск verify(), вероятно, будет в порядке, потому что в приведенном выше методе нет другого способа получить значение , чем при вызове функции, которую вы бы verify использовали, и она возвращаетэто значение, так что вряд ли оно может быть вызвано более одного раза.

С другой стороны, если ваша функция выглядит следующим образом:

public int count() {
    // get a personService from an injector
    // log the personService's details
    // generate a random number
    // try calling count() on personService, catch an error
    // if you caught the error, return the random number
}

Тогда, возможно, вы делаете хотитедо verify(), потому что внезапно происходит много вещей, и некоторые из них (например, случайное число) могут быть сбиты с толку для правильного функционирования, даже если что-то идет ужасно неправильно.

0 голосов
/ 21 января 2019

Да, вы все делаете правильно.

Вы вводите фиктивный репозиторий в реальный сервис, а затем тестируете сервис. Когда дело доходит до бизнес-логики в вашем сервисе, все может происходить. Вот почему важно проверять код с известными входами и известными выходами, как вы делаете.

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

  2. и 3. Проверка и assertEquals тестируют разные вещи. Проверка проверяет, был ли вызван ваш метод репозитория, а проверка проверяет, что служба ответила правильным значением. Представьте, что ваш метод обслуживания имеет жестко запрограммированную return 2L. AssertEquals пройдет, но проверка не удастся.

  3. Да, вы все делаете правильно. То, что вы тестируете, связано с тем, почему вы тестируете. Требуется ли конкретное утверждение или проверка, обычно зависит от конкретной ситуации. В этом случае нет смысла тестировать, что ваш метод репозитория возвращает 2L, но есть хороший пример для тестирования того, что ваша служба возвращает 2L. Точно так же нет смысла проверять, что был вызван метод службы, но есть хороший пример для проверки того, что был вызван метод хранилища.

Теперь у вас есть инструменты для тестирования вашего сервиса, следующий шаг - определить, какие тесты писать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...