一键导入
testing-junit
JUnit 5 testing patterns with Mockito and AssertJ
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
JUnit 5 testing patterns with Mockito and AssertJ
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Core Java patterns, modern Java features (JDK 17+), best practices
Maven and Gradle build tools, dependency management, multi-module projects
Spring Boot 3 patterns for controllers, services, configuration, and validation
Spring Data JPA and Hibernate patterns for entities, repositories, and query performance
Spring Security 6 patterns for authentication, authorization, and OAuth2
Spring Boot testing with @SpringBootTest, MockMvc, and Testcontainers
| name | testing-junit |
| description | JUnit 5 testing patterns with Mockito and AssertJ |
| keywords | ["junit","junit5","test","testing","mockito","mock","stub","assertj","assertions","parameterized","integration test"] |
| filePatterns | ["*.java","pom.xml","build.gradle","build.gradle.kts"] |
| frameworks | ["junit","mockito","assertj"] |
| tokenCount | 1600 |
| version | 1.0.0 |
Practical testing patterns for Java services and APIs. Prefer readable tests over clever tests.
Read ONLY files relevant to the request! Use the content map to focus.
| File | Description | When to Read |
|---|---|---|
junit-basics.md | @Test, assertions, lifecycle | Unit test setup |
parameterized.md | @ParameterizedTest, sources | Data-driven tests |
mockito.md | @Mock, @InjectMocks, stubbing | Isolated unit tests |
assertj.md | Fluent assertions, collections | Readable assertions |
spring-slices.md | @WebMvcTest, @DataJpaTest | Framework-level tests |
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void findById_whenExists_returnsUser() {
var user = User.create("u1", "dev@example.com");
when(userRepository.findById("u1")).thenReturn(Optional.of(user));
var result = userService.findById("u1");
assertThat(result).isPresent();
assertThat(result.get().getEmail()).isEqualTo("dev@example.com");
}
}
@ParameterizedTest
@ValueSource(strings = {"a@b.com", "user@company.io"})
void validateEmail_acceptsValid(String email) {
var result = EmailValidator.isValid(email);
assertThat(result).isTrue();
}
@ParameterizedTest
@CsvSource({
"PENDING, true",
"ACTIVE, false"
})
void isInactive_flagsStatus(String status, boolean expected) {
assertThat(UserStatus.valueOf(status).isInactive()).isEqualTo(expected);
}
@Test
void createUser_savesEntity() {
var request = new CreateUserRequest("dev@example.com", "Dev");
when(userRepository.existsByEmail(request.email())).thenReturn(false);
userService.create(request);
verify(userRepository).save(any(User.class));
}
@Test
void updateUser_throwsWhenMissing() {
when(userRepository.findById("missing")).thenReturn(Optional.empty());
assertThatThrownBy(() -> userService.update("missing", new UpdateUserRequest("name")))
.isInstanceOf(ResourceNotFoundException.class)
.hasMessageContaining("User");
}
assertThat(users)
.hasSize(3)
.extracting(User::getEmail)
.contains("dev@example.com");
assertThat(response)
.returns(HttpStatus.CREATED, ResponseEntity::getStatusCode)
.extracting(ResponseEntity::getBody)
.isNotNull();
@Nested
class CreateUserTests {
@Test
void rejectsDuplicateEmail() { }
@Test
void hashesPassword() { }
}
@BeforeEach
void setup() {
// Use only for shared, simple setup
}
| Anti-Pattern | Why Bad | Better Approach |
|---|---|---|
| Testing private methods | Refactoring pain | Test public behavior |
| Mocking everything | Brittle tests | Mock only boundaries |
| Multiple behaviors per test | Hard to debug | Split into focused tests |
| Asserting via logs | Not deterministic | Assert on outcomes |
| Need | Skill |
|---|---|
| Java patterns | @[skills/java-expert] |
| Build tools | @[skills/maven-gradle] |