unit-test-service-layer — скилл для Claude Code: тесты сервисов
Скилл задаёт агенту шаблон юнит-тестов сервисного слоя на Mockito: моки репозиториев, проверка вызовов, сценарии с исключениями.
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a claude-codeЧто делает unit-test-service-layer
Скилл описывает рабочий процесс для тестирования классов @Service: подключить @ExtendWith(MockitoExtension.class), объявить зависимости через @Mock, тестируемый сервис — через @InjectMocks. Дальше Arrange-Act-Assert: подготовить данные и настроить возвраты моков через when().thenReturn(), вызвать метод, проверить результат ассертами AssertJ и взаимодействия через verify(). На каждом шаге есть точка проверки — прогон теста и зелёная полоса.
Отдельно разобраны исключения: мок настраивается на when().thenThrow(), тест проверяет тип и сообщение ошибки. В конце — прогон всего набора (mvn test или gradle test) и отчёт покрытия через mvn test jacoco:report. Внутри скилла лежит файл references/examples.md с дополнительными сценариями: несколько зависимостей, argument captors, асинхронные сервисы, проверка порядка вызовов через InOrder.
Есть жёсткие ограничения, и они важнее примеров. Value objects и DTO не мокаются — создаются реальные экземпляры с тестовыми данными. Матчеры вроде any() и eq() нельзя смешивать с конкретными значениями в одном стабе, иначе стаб не сработает. Приватные методы напрямую не тестируются, только через публичное поведение. Если у сервиса слишком много зависимостей для моков, это повод задуматься о рефакторинге, а не тащить в тест всё подряд.
Какие задачи решает
- написать юнит-тест сервиса без поднятия Spring-контекста и базы
- замокать репозиторий и проверить, что сервис вызвал его с нужным аргументом
- проверить, что метод бросает нужное исключение при пустом результате
- застабить ответ внешнего клиента, чтобы тест не ходил в сеть
- разложить тест на Arrange-Act-Assert и не забыть про проверку взаимодействий
Примеры запросов агенту
- Напиши юнит-тесты для
UserServiceна Mockito: замокайUserRepository, проверь возврат пользователя и сценарий сUserNotFoundException. - Добавь тест, который проверяет, что при регистрации нового пользователя вызывается
emailService.sendWelcomeEmail. - Прогони тесты через
mvn testи покажи, какие методы сервиса остались без покрытия.
Как установить unit-test-service-layer
1Через Skills CLI (Vercel)
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a claude-code2Вручную: положить файлы
~/.claude/skills/unit-test-service-layer/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/unit-test-service-layer/
1Через Skills CLI (Vercel)
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a codex2Вручную: положить файлы
.agents/skills/unit-test-service-layer/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a cursor2Вручную: положить файлы
.cursor/skills/unit-test-service-layer/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install giuseppe-trisciuoglio/developer-kit unit-test-service-layer2Вручную: положить файлы
.github/skills/unit-test-service-layer/SKILL.md1Через Skills CLI (Vercel)
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a gemini-cli2Командой платформы
gemini skills install https://github.com/giuseppe-trisciuoglio/developer-kit --path plugins/developer-kit-java/skills/unit-test-service-layerВручную: положить файлы
.devin/skills/unit-test-service-layer/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о unit-test-service-layer
Как установить unit-test-service-layer в Claude?
Выполните npx skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-service-layer -a claude-code. Скилл появится в ~/.claude/skills/unit-test-service-layer/SKILL.md.
Что делает unit-test-service-layer?
Даёт агенту шаблоны юнит-тестов сервисного слоя на Mockito: моки репозиториев и клиентов, проверка вызовов, сценарии с исключениями. Тесты идут без Spring-контейнера и обращений к базе.
Чем этот скилл отличается от интеграционных тестов?
Он нацелен на изолированные тесты бизнес-логики: зависимости подменяются моками, поэтому база и внешние API в прогоне не участвуют.
Исходный текст
SKILL.md · MIT
---
name: unit-test-service-layer
description: Provides patterns for unit testing service layer with Mockito. Creates isolated tests that mock repository calls, verify method invocations, test exception scenarios, and stub external API responses. Use when testing service behaviors and business logic without database or external services.
allowed-tools: Read, Write, Bash, Glob, Grep
---
# Unit Testing Service Layer with Mockito
## Overview
Provides patterns for unit testing `@Service` classes using Mockito. Mocks repository calls, verifies method invocations, tests exception scenarios, and stubs external API responses. Enables fast, isolated tests without Spring container or database.
## When to Use
- Testing business logic in `@Service` classes
- Mocking repository and external client dependencies
- Verifying service interactions with mocked collaborators
- Testing error handling and edge cases in services
- Writing fast, isolated unit tests (no database, no API calls)
## Instructions
Follow this workflow to test service layer with Mockito, including validation checkpoints:
### 1. Setup Test Class
Use `@ExtendWith(MockitoExtension.class)` to enable Mockito annotations.
### 2. Declare Mocks with `@Mock` and `@InjectMocks`
Use `@Mock` for dependencies (repositories, clients) and `@InjectMocks` for the service under test.
### 3. Arrange-Act-Assert with Validation
**Arrange**: Create test data and configure mock return values using `when().thenReturn()`.
**Act**: Execute the service method being tested.
**Assert**:
- Verify returned values with AssertJ assertions
- Verify mock interactions with `verify()`
- **Validation checkpoint**: Run test and confirm green bar
### 4. Test Exception Scenarios
Configure mocks to throw exceptions with `when().thenThrow()`.
**Validation checkpoint**: Verify exception type and message
### 5. Verify Complete Coverage
- Run full test suite: `mvn test` or `gradle test`
- Check coverage report: `mvn test jacoco:report`
- **Validation checkpoint**: Confirm all service methods have corresponding tests
## Examples
### Basic Service Test Pattern
```java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldReturnUserWhenFound() {
// Arrange
User expected = new User(1L, "Alice");
when(userRepository.findById(1L)).thenReturn(Optional.of(expected));
// Act
User result = userService.getUser(1L);
// Assert
assertThat(result.getName()).isEqualTo("Alice");
verify(userRepository).findById(1L);
}
@Test
void shouldThrowWhenUserNotFound() {
// Arrange
when(userRepository.findById(999L)).thenReturn(Optional.empty());
// Act & Assert
assertThatThrownBy(() -> userService.getUser(999L))
.isInstanceOf(UserNotFoundException.class);
}
}
```
### Verify Method Invocations
```java
@Test
void shouldSendEmailOnUserCreation() {
User newUser = new User(1L, "Alice", "[email protected]");
when(userRepository.save(any(User.class))).thenReturn(newUser);
enrichmentService.registerNewUser("Alice", "[email protected]");
verify(userRepository).save(any(User.class));
verify(emailService).sendWelcomeEmail("[email protected]");
}
```
For additional patterns (multiple dependencies, argument captors, async services, InOrder verification), see `references/examples.md`.
## Best Practices
- **Use `@ExtendWith(MockitoExtension.class)`** for JUnit 5 integration
- **Mock only direct dependencies** of the service under test
- **Verify interactions** to ensure correct collaboration
- **Test one behavior per test method** - keep tests focused
- **Use descriptive variable names**: `expectedUser`, `actualUser`, `captor`
- **Create real instances** for value objects and DTOs (don't mock them)
## Constraints and Warnings
- Do not mock value objects or DTOs; create real instances with test data.
- Avoid mocking too many dependencies; consider refactoring if a service has too many collaborators.
- Tests must be independent; do not rely on execution order.
- Be cautious with `@Spy`; partial mocking is harder to understand and maintain.
- Do not test private methods directly; test them through public method behavior.
- Argument matchers (`any()`, `eq()`) cannot be mixed with actual values in the same stub.
- Avoid over-verifying; verify only interactions important to the test scenario.
## References
- [Mockito Documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html)
- [JUnit 5 User Guide](https://junit.org/junit5/docs/current/user-guide/)
- [AssertJ Assertions](https://assertj.github.io/assertj-core-features-highlight.html)
© giuseppe-trisciuoglio · MIT · giuseppe-trisciuoglio/developer-kit