You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<rule-title>Use Parameterized Tests for Data Variations</rule-title>
364
-
<rule-subtitle>Use @ParameterizedTest for testing the same logic with different inputs</rule-subtitle>
364
+
<rule-subtitle>Use `@ParameterizedTest` for testing the same logic with different inputs</rule-subtitle>
365
365
</rule-header>
366
366
<rule-description>
367
367
When testing a method's behavior across various input values or boundary conditions, leverage JUnit 5's parameterized tests (`@ParameterizedTest` with sources like `@ValueSource`, `@CsvSource`, `@MethodSource`). This avoids code duplication and clearly separates the test logic from the test data.
@@ -435,6 +435,29 @@ class RepetitiveCalculatorTest {
435
435
<rule-description>
436
436
Unit tests should focus solely on the logic of the class being tested (System Under Test - SUT), not its dependencies (database, network services, other classes). Use mocking frameworks like Mockito to create mock objects that simulate the behavior of these dependencies. This ensures tests are fast, reliable, and truly test the unit in isolation.
<note-description>Defines the behavior of a mock object's method. When the specified method is called on the mock, it will return the defined `value`.</note-description>
<note-description>Verifies that a specific method was called on the mock object. You can also specify the number of times (`times(n)`), at least once (`atLeastOnce()`), etc.</note-description>
451
+
</note-item>
452
+
<note-item>
453
+
<note-term>`@Mock` Annotation</note-term>
454
+
<note-description>Used with `@ExtendWith(MockitoExtension.class)` (JUnit 5) to automatically create mocks for fields.</note-description>
455
+
</note-item>
456
+
<note-item>
457
+
<note-term>`@InjectMocks` Annotation</note-term>
458
+
<note-description>Creates an instance of the class under test and automatically injects fields annotated with `@Mock` into it.</note-description>
// Verify that save was called with the correct user object (or use ArgumentCaptor for complex cases)
533
+
verify(userRepository).save(userToSave);
534
+
}
477
535
}]]></code-block>
478
536
</good-example>
479
537
<bad-example>
@@ -505,7 +563,7 @@ class UserServiceTestBad {
505
563
<rule-subtitle>Use code coverage as a guide, not a definitive quality metric</rule-subtitle>
506
564
</rule-header>
507
565
<rule-description>
508
-
Tools like JaCoCo can measure which lines of code are executed by your tests (code coverage). Aiming for high coverage (e.g., >80% line/branch coverage) is generally good practice, as it indicates most code paths are tested. However, 100% coverage doesn't guarantee bug-free code or high-quality tests. Focus on writing meaningful tests for critical logic and edge cases rather than solely chasing coverage numbers.
566
+
Tools like JaCoCo can measure which lines of code are executed by your tests (code coverage). Aiming for high coverage (e.g., >80% line/branch coverage) is generally good practice, as it indicates most code paths are tested. However, 100% coverage doesn't guarantee bug-free code or high-quality tests. Focus on writing meaningful tests for critical logic and edge cases rather than solely chasing coverage numbers. A test might cover a line but not actually verify its correctness effectively.
509
567
</rule-description>
510
568
</rule-section>
511
569
@@ -535,7 +593,7 @@ class UserServiceTestBad {
535
593
<rule-subtitle>Avoid common testing anti-patterns</rule-subtitle>
536
594
</rule-header>
537
595
<rule-description>
538
-
Testing Implementation Details: Avoid testing implementation details that might change, leading to brittle tests. Focus on testing behavior and outcomes. Hard-coded Values: Avoid hard-coding values in tests. Use constants or test data to make tests more maintainable. Complex Test Logic: Keep test logic simple and avoid complex calculations or conditional statements within tests.
596
+
Testing Implementation Details: Avoid testing implementation details that might change, leading to brittle tests. Focus on testing behavior and outcomes. Hard-coded Values: Avoid hard-coding values in tests. Use constants or test data to make tests more maintainable. Complex Test Logic: Keep test logic simple and avoid complex calculations or conditional statements within tests. Ignoring Edge Cases: Don't ignore edge cases or boundary conditions. Ensure tests cover a wide range of inputs, including invalid or unexpected values. Slow Tests: Avoid slow tests that discourage developers from running them frequently. Over-reliance on Mocks: Mock judiciously; too many mocks can obscure the actual behavior and make tests less reliable. Ignoring Test Failures: Never ignore failing tests. Investigate and fix them promptly.
539
597
</rule-description>
540
598
</rule-section>
541
599
@@ -545,7 +603,9 @@ class UserServiceTestBad {
545
603
<rule-subtitle>Ensure proper state isolation between tests</rule-subtitle>
546
604
</rule-header>
547
605
<rule-description>
548
-
Isolated State: Ensure each test has its own isolated state to avoid interference between tests. Use @BeforeEach to reset the state before each test. Immutable Objects: Prefer immutable objects to simplify state management and avoid unexpected side effects. Stateless Components: Design stateless components whenever possible to reduce the need for state management in tests.
606
+
- **Isolated State:** Ensure each test has its own isolated state to avoid interference between tests. Use `@BeforeEach` to reset the state before each test.
607
+
- **Immutable Objects:** Prefer immutable objects to simplify state management and avoid unexpected side effects.
608
+
- **Stateless Components:** Design stateless components whenever possible to reduce the need for state management in tests.
549
609
</rule-description>
550
610
</rule-section>
551
611
@@ -555,7 +615,9 @@ class UserServiceTestBad {
555
615
<rule-subtitle>Test error conditions and exception handling</rule-subtitle>
556
616
</rule-header>
557
617
<rule-description>
558
-
Expected Exceptions: Use AssertJ's assertThatThrownBy to verify that a method throws the expected exception under specific conditions. Exception Messages: Assert the exception message to ensure the correct error is being thrown with helpful context. Graceful Degradation: Test how the application handles errors and gracefully degrades when dependencies are unavailable.
618
+
- **Expected Exceptions:** Use AssertJ's `assertThatThrownBy` to verify that a method throws the expected exception under specific conditions.
619
+
- **Exception Messages:** Assert the exception message to ensure the correct error is being thrown with helpful context.
620
+
- **Graceful Degradation:** Test how the application handles errors and gracefully degrades when dependencies are unavailable.
559
621
</rule-description>
560
622
</rule-section>
561
623
@@ -565,8 +627,133 @@ class UserServiceTestBad {
565
627
<rule-subtitle>Utilize JSpecify annotations for explicit nullness contracts</rule-subtitle>
566
628
</rule-header>
567
629
<rule-description>
568
-
Employ JSpecify annotations (org.jspecify.annotations.*) such as @NullMarked, @Nullable, and @NonNull to clearly define the nullness expectations of method parameters, return types, and fields within your tests and the code under test. This practice enhances code clarity, enables static analysis tools to catch potential NullPointerExceptions early, and improves the overall robustness of your tests and application code.
630
+
Employ JSpecify annotations (org.jspecify.annotations.*) such as @NullMarked, @Nullable, and @NonNull to clearly define the nullness expectations of method parameters, return types, and fields within your tests and the code under test. This practice enhances code clarity, enables static analysis tools to catch potential NullPointerExceptions early, and improves the overall robustness of your tests and application code. In test code, this is particularly important for defining the expected behavior of mocks and verifying interactions with potentially null values.
0 commit comments