JUnit 5easy0-2 years
In one JUnit 5 test class, `rejectsDuplicateEmail` passes when run on its own and fails when the whole class runs. The class keeps a `static List<Customer> saved` for its in-memory repository, and last week someone added `@TestInstance(Lifecycle.PER_CLASS)` so a `@BeforeAll` method could stop being static. Explain the Jupiter lifecycle rule these two changes work against, and how you would fix the class.
By default Jupiter creates a new instance of the test class for every test method. Instance fields are therefore fresh for each test, so state cannot leak between them, and @BeforeAll has to be static because it runs before any instance exists. Both changes defeat that. A static field belongs to the class, not the instance, so rows saved by one test are still there for the next. PER_CLASS goes further: one instance for the whole class, so even ordinary fields now survive from test to test. The test passes alone because it starts with an empty list and fails in the class because an earlier test left a customer behind. The fix is to make the state per test again: an instance field created in @BeforeEach, and the default lifecycle.
PreviousA pull request adds a test for `Checkout`: it mocks `Discount`, stubs `apply(6000)` to return 5400, asserts that `checkout.total(6000)` is 5400, and verifies that `apply(6000)` was called. Coverage goes up and the build is green. The rule is 'orders **over** 5000 paise get 10% off', and the real `Discount` says `>=`. What does this test prove, and what would you write instead?Next A service has 800 unit tests that run in 4 seconds and 40 browser tests that take 25 minutes, and nothing in between. A repository query with a wrong `JOIN` shipped and was caught only by a browser test, three hours after the merge. Name the shape, explain why the unit tests could not have caught it, and say where you would add tests.