Перейти к содержимому

Как замокать void метод java

  • автор:

Mockito тестировние void метода

а что вы пытаетесь протестировать? опишите словами ваш тест.

2 янв 2017 в 7:45

Я хочу проверить, что метод delete получив id выполнит удаление и вернет true.

2 янв 2017 в 11:25

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Вот мой вариант.

public void delete(Long id) < // так делать плохо // добавлено по просьбе вопрошающего try < // проверку на существование и пр. должен делать MessageRepository messageRepository.delete(id); >catch(EmptyResultDataAccessException ex) < throw new DataNotFoundException("Data with not found."); >> 
private static final Long интерфейс, а не реализация private MessageRepository messageRepository; @Test public void detele_delegateToRepository() throws Exception < // подготовка messageRepository = mock(MessageRepository.class); // не знаю как у вас класс называется - будем считать Subject Subject subject = new Subject(messageRepository); // действие subject.delete(ID); // проверка verify(messageRepository).delete(ID); >@Test(expected = DataNotFoundException.class) public void detele_throwsException() throws Exception < // подготовка messageRepository = mock(MessageRepository.class); // не знаю как у вас класс называется - будем считать Subject Subject subject = new Subject(messageRepository); when(messageRepository.delete(ID)).thenThrow(new EmptyResultDataAccessException()); // действие subject.delete(ID); >

Это все что вам надо тестировать. Остальные тесты должны быть у класса который реализует MessageRepository.

Как протестировать void метод с помощью java

Для тестирования void методов в Java используются различные техники, такие как написание юнит-тестов с использованием фреймворков для тестирования, например JUnit или TestNG , или написание тестовых классов вручную.

Для тестирования void метода мы можем создать экземпляр тестируемого класса, вызвать его метод и затем проверить, что он выполнился правильно. Например, если есть метод void incrementCounter() , который должен увеличивать значение счетчика на единицу, мы можем написать следующий тестовый метод:

import org.junit.Test; import static org.junit.Assert.assertEquals; @Test public void testIncrementCounter()  // Arrange MyClass myClass = new MyClass(); int initialCounterValue = myClass.getCounter(); // Act myClass.incrementCounter(); // Assert int newCounterValue = myClass.getCounter(); assertEquals(initialCounterValue + 1, newCounterValue); > 

В этом тестовом методе мы создаем экземпляр класса MyClass , получаем начальное значение счетчика, вызываем метод incrementCounter() , а затем проверяем, что значение счетчика увеличилось на единицу.

Мокирование void методов с помощью Mockito

Один из самых распространенных вопросов, возникающих при работе с Mockito, — как замокировать методы с возвращаемым типом void. Это может быть требуемо во многих ситуациях, особенно при использовании паттерна Observer, где методы часто не возвращают значения.

Допустим, есть класс World , который содержит метод addListener , добавляющий слушателей, и метод doAction , который выполняет некоторое действие и обновляет состояние системы.

public class World < List<Listener> listeners; void addListener(Listener item) < listeners.add(item); >void doAction(Action goal,Object obj) < setState("i received"); goal.doAction(obj); setState("i finished"); >private String state; //setter getter state >

И есть тестовый класс WorldTest , который пытается замокировать World и добавить себя в качестве слушателя.

public class WorldTest implements Listener < @Test public void word< World w= mock(World.class); w.addListener(this); . . >>

Здесь возникает проблема: система не реагирует на добавление мока.

В Mockito есть инструменты для решения этой проблемы. Вместо того чтобы вызывать метод addListener напрямую, можно использовать конструкцию doNothing().when() .

doNothing().when(mockedObject).voidMethod();

В данном случае, это будет выглядеть так:

doNothing().when(w).addListener(this);

После этого, можно вызвать addListener без проблем. Вызов doNothing().when() гарантирует, что ничего не будет сделано при вызове метода. Это идеально подходит для методов с void возвратом, так как они, по определению, ничего не возвращают.

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

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

Популярные сценарии работы с Mockito

И еще один важный момент – мокирование и верификация статических методов. “А что в этом такого?”, – спросишь ты. Да, статические, но ведь методы же. И будете неправы.

Помни, с чего мы начали изучение мок-объектов? С того, что эти объекты искусственно создаются через класс DynamicProxy . А статические методы ни к каким объектам не привязаны и перехватить вызовы к ним через DynamicProxy нельзя . Вот и все.

Но создатели Mockito и тут смогли извернуться – написали свой загрузчик классов и с его помощью смогли подменять классы на лету. Большая и сложная работа, но они все-таки смогли это сделать.

Понадобится добавить дополнительную библиотеку в pom.xml :

 org.mockito mockito-inline 4.2.0 test  

Вот как нужно работать, если вам нужно мокировать статический метод.

1 Создаем специальный мок-объект класса:

MockedStaticИмяКласса>управляющийОбъект = Mockito.mockStatic(ИмяКласса.class);

2 Добавляем к этому объекту правила работы:

К этому объекту правила нужно цеплять другими способами.

управляющийОбъект.when(ИмяКласса::имяМетода).thenReturn(результат);

3 Обязательно заворачиваем использование этого объекта в try-with-resources , чтобы объект сразу удалился и Mockito могло очистить связанные с ним правила.

 @Test void givenStaticMethodWithNoArgs () < try (MockedStatic< StaticUtils> utilities = Mockito.mockStatic( StaticUtils.class)) < //добавляем правило utilities.when(StaticUtils::name).thenReturn("Привет"); //проверяем, что правило работает assertEquals("Привет", StaticUtils.name()); > > 

Не так красиво, как с аннотациями @Mock и @Spy , зато очень практично. Было очень тяжело писать тесты, когда нельзя было замокать простой статический метод, который использовался внутри тестируемых методов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *