0%
Test Data

Test data

Test builders, isolation, rolled-back transactions, and datasets that age badly.

10-15 min

Test Data

This test fails. Figure out why in ten seconds:

@Test
void une_commande_expediee_ne_peut_plus_etre_annulee() {
    Client client = new Client(1L, "Alice", "alice@example.com", "12 rue des Lilas",
                               "75011", "Paris", "FR", true, false, null,
                               LocalDate.of(2024, 1, 1), Statut.ACTIF, 0, null);
    Commande commande = new Commande(10L, client, List.of(
        new Ligne(1L, "REF-1", 2, new BigDecimal("19.99"), new BigDecimal("0.20"))),
        LocalDateTime.now(), StatutCommande.EXPEDIEE, null, null, "FR", false);

    assertThatThrownBy(() -> service.annuler(commande)).isInstanceOf(CommandeExpedieeException.class);
}

You can't. The only detail that matters, StatutCommande.EXPEDIEE, is buried among eighteen values unrelated to the intent of the test. And the day a field is added to the constructor, the eighty tests built on this model all stop compiling at once.

This is the sneakiest debt in a test suite: it shows up in neither coverage nor execution time, yet it triples the cost of writing each new test and makes every failure unreadable. A good test object makes what matters visible and what doesn't matter invisible. The rest of this lesson shows how, then tackles the second problem with test data: isolation between tests, where the easy solutions hide trade-offs you need to know about.

Comments

Comments are powered by GitHub Discussions

Sign in with GitHub to join the discussion

Link copied!