1+ package spring .oldboy .service ;
2+
3+ import org .junit .jupiter .api .Test ;
4+ import org .junit .jupiter .api .extension .ExtendWith ;
5+ import org .mockito .InjectMocks ;
6+ import org .mockito .Mock ;
7+ import org .mockito .junit .jupiter .MockitoExtension ;
8+ import org .springframework .context .ApplicationEventPublisher ;
9+ import spring .oldboy .database .entity .Company ;
10+ import spring .oldboy .database .repository .company_repository .CompanyRepository ;
11+ import spring .oldboy .dto .CompanyReadDto ;
12+ import spring .oldboy .listener .EntityEvent ;
13+
14+ import java .util .Collections ;
15+ import java .util .Optional ;
16+
17+ import static org .junit .jupiter .api .Assertions .assertEquals ;
18+ import static org .junit .jupiter .api .Assertions .assertTrue ;
19+ import static org .mockito .Mockito .*;
20+
21+ /* Для обработки аннотаций @Mock и @InjectMocks */
22+ @ ExtendWith (MockitoExtension .class )
23+ class CompanyServiceTest {
24+
25+ /* Нам нужна переменная которая будет передаваться при создании новой Company */
26+ private static final Integer COMPANY_ID = 1 ;
27+ /*
28+ От классов: CompanyRepository, UserService и ApplicationEventPublisher зависит класс
29+ CompanyService поэтому мы помечаем их соответствующей аннотацией т.е. создаем для них
30+ mock объекты - заглушки.
31+ */
32+ @ Mock
33+ private CompanyRepository companyRepository ;
34+ @ Mock
35+ private UserService userService ;
36+ @ Mock
37+ private ApplicationEventPublisher eventPublisher ;
38+ /*
39+ При unit-тестировании нам нужен экземпляр CompanyService для тестирования метода *.findById(). Однако,
40+ сам данный класс так же зависит от, CompanyRepository, UserService и ApplicationEventPublisher. Значит,
41+ нам их нужно откуда-то взять или создать на них некие удобоваримые заглушки ('замокать'), см. выше, а в
42+ наш CompanyService внедрить эти 'моки' см. примеры работы с Mockito (там-же раздел DOC):
43+ https://github.com/JcoderPaul/Junit5_Tests/tree/master/Junit5_Mockito_lesson_8
44+ https://github.com/JcoderPaul/Junit5_Tests/tree/master/Junit5_Mockito_lesson_9
45+ */
46+ @ InjectMocks
47+ private CompanyService companyService ;
48+
49+ @ Test
50+ void findById () {
51+ /*
52+ Метод ниже, возвращает STUB-объект, который используется mocks и spies для создания ответа
53+ (Answer) на вызовы методов во время тестов. Если читать строку, то получим, что мы просим
54+ Mockito вернуть (toBeReturn) - true, (when) когда мы вызовем у CompanyRepository метод
55+ *.findById() и передадим в него ID. Т.е Mockito поставит нам объект Company.
56+ */
57+ doReturn (Optional .of (new Company (COMPANY_ID , null , Collections .emptyMap ())))
58+ .when (companyRepository ).findById (COMPANY_ID );
59+ /* Теперь мы пытаемся получить mock-прокси объект */
60+ Optional <CompanyReadDto > actualResult = companyService .findById (COMPANY_ID );
61+ /* И проверяем его наличие, т.е. мы все же ожидаем его получить и если он существует, то */
62+ assertTrue (actualResult .isPresent ());
63+ /*
64+ Создаем CompanyReadDto с заданным ID - т.е. берем ожидаемый
65+ результат с которым и будем сравнивать актуальный результат
66+ */
67+ CompanyReadDto expectedResult = new CompanyReadDto (COMPANY_ID );
68+ /*
69+ Метод *.ifPresent() позволяет выполнить какое-то действие, если объект не пустой.
70+
71+ Простой тест с OPTIONAL объектом мог бы выглядеть так:
72+
73+ @Test
74+ public void givenOptionalWhenIfPresentWorksThenCorrect() {
75+ Optional<String> opt = Optional.of("oldboy");
76+ opt.ifPresent(name -> System.out.println(name.length()));
77+ }
78+
79+ что мы и реализуем ниже, т.е. при наличии, актуального результата сравниваем его с
80+ ожидаемым на эквивалентность.
81+ */
82+ actualResult .ifPresent (actual -> assertEquals (expectedResult , actual ));
83+ /*
84+ Mockito предоставляет массу методов для контроля над проведением тестов,
85+ а так же взаимодействия с результатами тестов в процессе. Это механизм
86+ verify - верификации.
87+
88+ Тут мы проверяем отправлен ли был event (событие зафиксировано)
89+ */
90+ verify (eventPublisher ).publishEvent (any (EntityEvent .class ));
91+ verifyNoMoreInteractions (eventPublisher , userService );
92+ }
93+ }
0 commit comments