[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-spring-test-kak-testirovat-servisnyy-sloy-s-pomoshchyu-mockitoextension":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":15,"progress":16,"seo":17},699,"kak-testirovat-servisnyy-sloy-s-pomoshchyu-mockitoextension",16,"spring-test","Spring Test","🧪","Как тестировать сервисный слой с помощью MockitoExtension?","Для юнит-тестирования сервисного слоя не нужен контекст Spring. Используется `@ExtendWith(MockitoExtension.class)` совместно с `@Mock` и `@InjectMocks`.\n\n- `@Mock` — создаёт мок-объект для зависимости.\n- `@InjectMocks` — создаёт экземпляр тестируемого класса и внедряет в него все моки.\n\n\u003Cdetails>\u003Csummary>Полный пример теста сервиса\u003C\u002Fsummary>\n\n```java\n@ExtendWith(MockitoExtension.class)\nclass UserServiceTest {\n\n    @Mock\n    private UserRepository userRepository;\n\n    @Mock\n    private EmailService emailService;\n\n    @Mock\n    private PasswordEncoder passwordEncoder;\n\n    @InjectMocks\n    private UserServiceImpl userService;\n\n    @Test\n    void shouldCreateUserSuccessfully() {\n        \u002F\u002F Arrange\n        UserDto dto = new UserDto(\"Иван\", \"ivan@example.com\", \"password\");\n        when(passwordEncoder.encode(\"password\")).thenReturn(\"encodedPassword\");\n        when(userRepository.save(any(User.class))).thenAnswer(invocation -> {\n            User user = invocation.getArgument(0);\n            user.setId(1L);\n            return user;\n        });\n\n        \u002F\u002F Act\n        User result = userService.create(dto);\n\n        \u002F\u002F Assert\n        assertNotNull(result.getId());\n        assertEquals(\"Иван\", result.getName());\n        assertEquals(\"encodedPassword\", result.getPassword());\n\n        verify(userRepository).save(any(User.class));\n        verify(emailService).sendWelcomeEmail(\"ivan@example.com\");\n    }\n\n    @Test\n    void shouldThrowExceptionWhenUserNotFound() {\n        when(userRepository.findById(999L)).thenReturn(Optional.empty());\n\n        assertThrows(UserNotFoundException.class,\n            () -> userService.findById(999L));\n\n        verify(userRepository).findById(999L);\n        verifyNoInteractions(emailService);\n    }\n\n    @Test\n    void shouldUpdateUserName() {\n        User existing = new User(1L, \"Иван\", \"ivan@example.com\");\n        when(userRepository.findById(1L)).thenReturn(Optional.of(existing));\n        when(userRepository.save(any(User.class))).thenReturn(existing);\n\n        User result = userService.updateName(1L, \"Пётр\");\n\n        assertEquals(\"Пётр\", result.getName());\n\n        ArgumentCaptor\u003CUser> captor = ArgumentCaptor.forClass(User.class);\n        verify(userRepository).save(captor.capture());\n        assertEquals(\"Пётр\", captor.getValue().getName());\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### Преимущества подхода\n\n- **Быстрота** — не поднимается контекст Spring\n- **Изоляция** — тестируется только логика сервиса\n- **Детерминированность** — нет зависимости от базы данных, сети и т.д.\n\n> **На собеседовании:** интервьюер хочет убедиться, что вы понимаете разницу между `@MockBean` (Spring-контекст) и `@Mock` + `@InjectMocks` (чистый Mockito). Частая ошибка — использовать `@SpringBootTest` для юнит-тестов сервисов вместо `MockitoExtension`.","","junior",[7],[],null,{"title":18,"description":19,"ogTitle":18,"ogDescription":20,"keywords":21,"schemaAnswer":19,"featuredSnippetReady":22},"Как тестировать сервисный слой с помощью MockitoExtension? — Gymterview","Для юнит-тестирования сервисного слоя не нужен контекст Spring. Используется `@ExtendWith(MockitoExtension.class)` совместно с `@Mock` и `@InjectMocks`.","Для юнит-тестирования сервисного слоя не нужен контекст Spring. Используется `@ExtendWith(MockitoExtension.class)` совме",[7,13],true]