Mockito.mock () срещу @Mock срещу @MockBean

1. Общ преглед

В този бърз урок ще разгледаме три различни начина за създаване на фалшиви обекти и как те се различават един от друг - с Mockito и с поддръжката за насмешка Spring

2. Mockito.mock ()

Методът Mockito.mock () ни позволява да създадем фиктивен обект от клас или интерфейс.

След това можем да използваме макета, за да заглушим връщаните стойности за неговите методи и да проверим дали са били извикани.

Нека разгледаме един пример:

@Test public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() { UserRepository localMockRepository = Mockito.mock(UserRepository.class); Mockito.when(localMockRepository.count()).thenReturn(111L); long userCount = localMockRepository.count(); Assert.assertEquals(111L, userCount); Mockito.verify(localMockRepository).count(); }

Този метод не се нуждае от нищо друго, за да се направи, преди да може да се използва. Можем да го използваме за създаване на фиктивни полета на клас, както и локални макети в метод.

3. Mockito's @Mock Annotation

Тази анотация е стенография за метода Mockito.mock () . Освен това трябва да го използваме само в тестов клас. За разлика от метода mock () , ние трябва да активираме анотациите на Mockito да използват тази анотация.

Можем да направим това, като използваме MockitoJUnitRunner, за да стартираме теста, или изрично извикаме метода MockitoAnnotations.initMocks () .

Нека разгледаме пример, използващ MockitoJUnitRunner :

@RunWith(MockitoJUnitRunner.class) public class MockAnnotationUnitTest { @Mock UserRepository mockRepository; @Test public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { Mockito.when(mockRepository.count()).thenReturn(123L); long userCount = mockRepository.count(); Assert.assertEquals(123L, userCount); Mockito.verify(mockRepository).count(); } }

Освен че прави кода по-четлив, @Mock улеснява намирането на макет на проблема в случай на отказ, тъй като името на полето се появява в съобщението за отказ:

Wanted but not invoked: mockRepository.count(); -> at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22) Actually, there were zero interactions with this mock. at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22) 

Също така, когато се използва заедно с @InjectMocks , той може значително да намали количеството на кода за настройка.

4. Анотация на @MockBean на Spring Boot

Можем да използваме @MockBean, за да добавим фиктивни обекти към контекста на приложението Spring. Мокетът ще замени всеки съществуващ боб от същия тип в контекста на приложението.

Ако не е дефиниран боб от същия тип, ще бъде добавен нов. Тази анотация е полезна при тестове за интеграция, където даден боб - например външна услуга - трябва да бъде подиграван.

За да използваме тази анотация, трябва да използваме SpringRunner, за да стартираме теста:

@RunWith(SpringRunner.class) public class MockBeanAnnotationIntegrationTest { @MockBean UserRepository mockRepository; @Autowired ApplicationContext context; @Test public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { Mockito.when(mockRepository.count()).thenReturn(123L); UserRepository userRepoFromContext = context.getBean(UserRepository.class); long userCount = userRepoFromContext.count(); Assert.assertEquals(123L, userCount); Mockito.verify(mockRepository).count(); } }

Когато използваме анотацията в поле, освен че сме регистрирани в контекста на приложението, макетът също ще бъде инжектиран в полето.

Това е видно от горния код. Тук използвахме инжектирания макет на UserRepository, за да заглушим метода на броене . След това използвахме bean от контекста на приложението, за да проверим дали наистина е подиграваният bean.

5. Заключение

В тази статия видяхме как се различават трите метода за създаване на фиктивни обекти и как всеки може да се използва.

Изходният код, придружаващ тази статия, е достъпен в GitHub.