mcpField
J
junit-5-skill

junit-5-skill

github.com/lambdatestテスト・品質384261 回インストール2 週間前に更新
リポジトリ

junit-5-skill について

Java 開発者向けの JUnit 5 テストスキルです。一般的なテスト形式、Mockito の利用方法、本番向けのテストパターンを扱います。

主な機能

  1. 01単体テストと統合テストのガイド
  2. 02パラメーター化テストとネストテスト
  3. 03Mockito のテストパターン
  4. 04アサーションとライフサイクルの資料
  5. 05Maven と Gradle のテストコマンド

活用シーン

  1. 01Java の単体テスト作成
  2. 02Mockito を使ったサービスのテスト
  3. 03パラメーター化テストケースの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lambdatest/agent-skills --skill junit-5-skill

インストール後、Claude Code で/junit-5-skillを入力して読み込まれたか確認します。

同梱ファイルreference/advanced-patterns.mdreference/playbook.md

詳細

JUnit 5 テストスキル

あなたは、JUnit 5 テストを専門とするシニア Java 開発者です。

ステップ 1 — テストの種類

├─ "unit test", "assert" → Standard unit test
├─ "parameterized", "multiple inputs" → @ParameterizedTest
├─ "mock", "Mockito" → Unit test with Mockito
├─ "integration test", "Spring" → Read reference/spring-integration.md
└─ Default → Standard unit test

基本パターン

基本的なテスト
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {
    private Calculator calculator;

    @BeforeEach
    void setUp() {
        calculator = new Calculator();
    }

    @Test
    @DisplayName("Addition of two positive numbers")
    void addPositiveNumbers() {
        assertEquals(5, calculator.add(2, 3));
    }

    @Test
    void divideByZero_throwsException() {
        assertThrows(ArithmeticException.class, () -> calculator.divide(10, 0));
    }

    @Test
    void multipleAssertions() {
        assertAll("calculator operations",
            () -> assertEquals(4, calculator.add(2, 2)),
            () -> assertEquals(0, calculator.subtract(2, 2)),
            () -> assertEquals(6, calculator.multiply(2, 3))
        );
    }
}
アサーションのリファレンス
assertEquals(expected, actual);
assertNotEquals(unexpected, actual);
assertTrue(condition);
assertFalse(condition);
assertNull(object);
assertNotNull(object);
assertThrows(IllegalArgumentException.class, () -> service.process(null));
assertTimeout(Duration.ofSeconds(2), () -> service.longRunningOp());
assertAll("group",
    () -> assertNotNull(user.getName()),
    () -> assertTrue(user.getAge() > 0)
);
assertIterableEquals(List.of(1, 2, 3), actualList);
パラメーター化テスト
@ParameterizedTest
@ValueSource(strings = {"hello", "world", "junit"})
void stringIsNotEmpty(String value) {
    assertFalse(value.isEmpty());
}

@ParameterizedTest
@CsvSource({"1,1,2", "2,3,5", "10,-5,5"})
void addNumbers(int a, int b, int expected) {
    assertEquals(expected, calculator.add(a, b));
}

@ParameterizedTest
@MethodSource("provideUsers")
void validateUser(String name, int age, boolean expected) {
    assertEquals(expected, validator.isValid(name, age));
}

static Stream<Arguments> provideUsers() {
    return Stream.of(
        Arguments.of("Alice", 25, true),
        Arguments.of("", 25, false),
        Arguments.of("Bob", -1, false)
    );
}

@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {"  ", "\t"})
void blankStringsAreInvalid(String input) {
    assertFalse(validator.isValid(input));
}
Mockito によるモック
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock private UserRepository userRepo;
    @Mock private EmailService emailService;
    @InjectMocks private UserService userService;

    @Test
    void createUser_savesAndSendsEmail() {
        User user = new User("[email protected]", "Alice");
        when(userRepo.save(any(User.class))).thenReturn(user);

        User result = userService.createUser("[email protected]", "Alice");

        assertNotNull(result);
        verify(userRepo).save(any(User.class));
        verify(emailService).sendWelcomeEmail("[email protected]");
    }

    @Test
    void getUser_notFound_throwsException() {
        when(userRepo.findById(99L)).thenReturn(Optional.empty());
        assertThrows(UserNotFoundException.class, () -> userService.getUser(99L));
    }
}
ネストされたテスト
@DisplayName("UserService")
class UserServiceTest {
    @Nested
    @DisplayName("when creating a user")
    class CreateUser {
        @Test void withValidData_succeeds() { }
        @Test void withDuplicateEmail_throwsException() { }
    }

    @Nested
    @DisplayName("when deleting a user")
    class DeleteUser {
        @Test void existingUser_removesFromDb() { }
        @Test void nonExistentUser_throwsException() { }
    }
}
アンチパターン
悪い例良い例理由
@Test public void test1()@Test void shouldCalculateSum()説明的な名前
プライベートメソッドをテストするパブリック API 経由でテストする実装の詳細
@DisplayName を付けない常に表示名を付けるレポートが見やすくなる
assertEquals(true, x)assertTrue(x)より読みやすい

Maven の依存関係

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>5.14.0</version>
    <scope>test</scope>
</dependency>

クイックリファレンス

タスクコマンド
すべて実行mvn test または ./gradlew test
クラスを実行mvn test -Dtest=UserServiceTest
メソッドを実行mvn test -Dtest=UserServiceTest#createUser_succeeds
タグ付きで実行@Tag("slow") + mvn test -Dgroups="slow"
無効化@Disabled("Reason")
条件付き@EnabledOnOs(OS.LINUX)
タイムアウト@Timeout(value = 5, unit = TimeUnit.SECONDS)
繰り返し@RepeatedTest(5)
順序@TestMethodOrder(MethodOrderer.OrderAnnotation.class)

応用パターン

本番環境向けのパターンについては、reference/playbook.md を参照してください。

セクション内容
§1 プロジェクトのセットアップMaven の依存関係、並列実行の設定、Surefire
§2 テストのライフサイクルBeforeAll/Each、順序、タグ
§3 パラメーター化CsvSource、MethodSource、EnumSource、ValueSource
§4 Mockito@Mock/@InjectMocks、キャプター、検証の順序
§5 ネストされたテストと動的テスト@Nested によるグループ化、@TestFactory
§6 AssertJ流れるようなアサーション、extracting、コレクションのチェック
§7 条件付き@EnabledOnOs、assumptions、@EnabledIf
§8 カスタム拡張タイミング、再試行、BeforeTestExecution
§9 CI/CDテストレポーターを使った GitHub Actions
§10 デバッグ表よくある 8 つの問題と解決策
§11 ベストプラクティス本番環境向けチェックリスト 12 項目

コメント