Как я могу выполнить модульные функции void?

class Elephant extends Animal { public Elephant(String name) { super(name); } void makeNoise() { logger.info(" Elephant make Sound"); } void perform(String day) { if (day.equals("thursday") || day.equals("friday")) { makeNoise(); } } } 

Теперь я хочу протестировать метод perform . Как я могу проверить этот метод с помощью JUnit?

Решение с помощью Mockito Spy

 import org.junit.Test; import static org.mockito.Mockito.*; public class ElephantTest { @Test public void shouldMakeNoise() throws Exception { //given Elephant elephant = spy(new Elephant("foo")); //when elephant.perform("friday"); //then verify(elephant).makeNoise(); } } 

Отрицательные тесты:

 @Test public void elephantShouldDontMakeNoisesOnMonday() { //given Elephant elephant = spy(new Elephant("foo")); //when elephant.perform("monday"); //then verify(elephant, never()).makeNoise(); } 

или

 @Test public void shouldDoNotMakeNoisesOnMonday() { //given Elephant elephant = spy(new Elephant("foo")); //when elephant.perform("monday"); then(elephant).should(never()).makeNoise(); } 

зависимость

 org.mockito:mockito-core:2.21.0 

Прочитать о

  • Mockito # doNothing ()
  • Mockito # разведчик (Т)

Функции void() меняют состояние программы. Это можно сделать, изменив переменную, файл, базу данных и т. Д.

В вашем случае вы пишете регистратору. Если это приведет к записи «Elephant make Sound» в файл, вы можете прочитать этот файл и посмотреть, содержат ли данные в файле ваш шумный слон.

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

Следует отметить, что вы можете обойти DI путем насмешивания объекта и проверки соответствующих методов.

Чтобы протестировать любой метод, подлежащая тестированию ответственность должна быть видна с внешней стороны метода, изменяя состояние любой переменной.

Обычно это делается путем возврата значения из метода. Но без этого это можно сделать разными способами, изменив что-то из-за пределов метода, если у вас есть какая-то «проблема», чтобы вернуть что-то из этого метода!

В вашем случае вы регистрируете только сообщение. И ваш код на самом деле не может быть проверен в некотором смысле, что он не делает то, что напрямую связано с изменением состояния любой переменной (поскольку вы изменяете состояние другого ресурса, отличного от переменной, который не доступен напрямую вашим кодом. необходимо написать код для чтения изменений с этого внешнего ресурса, поэтому ваш тестовый код также зависит от чтения. Если у вас есть некоторые проблемы с чтением, ваш тестовый пример не пройдет, и это не соответствует духу единицы тестирование. Основная идея заключается в том, чтобы максимально уменьшить зависимость от внешних кодов или библиотек). Но ваш код можно проверить, выполнив небольшую рефакторинг / смещение ответственности, как показано ниже:

 String makeNoise() { return "Elephant make Sound"; } String perform(String day) { if (day.equals("thursday") || day.equals("friday")) { return makeNoise(); } } 

И тогда вы переносите ответственность за регистрацию значения, возвращаемого из метода perform на тот, который использует его, как показано ниже:

  logger.info(perform(day)); 

У вас есть различные варианты в зависимости от инструментов, которые вы готовы использовать, и глубины ваших тестов.

Частичное издевательство с простой Java

Создайте class (MockElephant), который простирается от слона, makeNoise чтобы он подсчитывал количество вызовов. Используйте этот class в своем тесте, чтобы проверить, что makeNoise было makeNoise правильным количеством раз

Частичное издевательство с каркасом. Вы в основном делаете то же, что и выше, но вместо ручного кодирования MockElephant вы создаете его, используя некоторую насмешливую структуру. Делает тест намного проще, так как вам нужно меньше кода. И читать легче. Но если происходят странные вещи, это затрудняет понимание того, что происходит. В случае Mocking frameworks я думаю, что они того стоят.

Причины, по которым это называется Partial Mocking, – это то, что вы издеваетесь над некоторыми частями classа (в этом случае один метод).

Альтернативой является использование Normal Mocks , что в вашем случае кажется выполнимым (но может стать жестким в устаревшем коде).

Здесь вы будете вводить Logger в качестве зависимости. Например, вы можете создать дополнительный конструктор, который позволит вам предоставить Logger. В вашем тесте вы использовали бы посмеянный Logger, который снова считает его invocations, вероятно, вместе с полученным параметром и проверяет, что он имеет ожидаемые значения.

Снова вы можете сделать это с помощью Mocking Framework или с простой старой Java.

  • Может ли Google выманить метод с типом возвращаемого интеллектуального указателя?
  • Формирование «грамматик» Mockito
  • Тестирование API Java EE 6
  • Единичное тестирование с одноточечными
  • Класс тестирования с новым вызовом () в нем с помощью Mockito
  • Тестирование модуля ASP.net Веб-сайт Код проекта, хранящийся в App_Code
  • Издевательские методы расширения с помощью Moq
  • Resharper запускает UnitTest из другого места
  • Вы добавляете модульные тесты в один проект или другой проект?
  • Как утверждать равенство на двух classах без метода equals?
  • Неплохо ли использовать рефлексию в модульном тестировании?
  • Давайте будем гением компьютера.