testcontainers / testcontainers/testcontainers-java

Spring Boot Tests with JUnit5 Jupiter and Shared Containers

Offen
#2,290 47 Kommentare 12 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

resolution/waiting-for-info
Vorherrschende Sprache
Java
Sterne
8.7k
Forks
1.9k
Ø Merge
2 T. 17 Std.
Gemergte PRs (30 T.)
9

Beschreibung

Currently, a typical test setup with Spring Boot tests and shared containers does not work anymore with JUnit 5: Using static testcontainers with Spring Boot's ApplicationContextInitializer to configure the server's ports in the Spring context.

The problem is that the Spring application context gets initialized during Jupiter extension's post processing while testcontainers are started during before all callbacks. The latter happens after post processing.

See
https://github.com/junit-team/junit5/blob/c9ae6e261550481362f17d21e88137a8c71fc7c8/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java#L184
vs.
https://github.com/junit-team/junit5/blob/c9ae6e261550481362f17d21e88137a8c71fc7c8/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java#L189

One approach to solve this could be to start the testcontainers also during post processing (TestInstancePostProcesso#postProcessTestInstancer)

Then the only remaining problem would be to ensure that the TestcontainersExtension always gets created before the SpringExtension.

Problematic Example

@SpringBootTest
@ContextConfiguration(initializers = {Initializer.class})
@Testcontainers
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class JupiterSharedTestcontainersTests {

  @Container
  public static JdbcDatabaseContainer postgreSQLContainer = new PostgreSQLContainer();

  @Test
  public void testTomatoes() {
    assertTrue("tomatoes".equals("tomatoes"));
  }
  
  public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
      TestPropertyValues.of(
          "spring.datasource.url=jdbc:postgresql://"
              + postgreSQLContainer.getContainerIpAddress()
              + ":" + postgreSQLContainer.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT)
              + "/db_name"
      ).applyTo(configurableApplicationContext.getEnvironment());
    }
  }

}

What do you think?

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem problematischen Spring Boot/Jupiter-Beispiel im Issue und vergleiche die Reihenfolge in JUnit Jupiter ClassBasedTestDescriptor.java um die referenzierten Zeilen 184 und 189. Reproduziere das Zusammenspiel zwischen ApplicationContextInitializer, Testcontainers und Jupiter-Callbacks und ermittle anschließend, ob eine unterstützte Reihenfolge das Setup des gemeinsamen Containers ermöglichen kann, ohne andere Erweiterungen zu beeinträchtigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
docker, java, postgresql, spring-boot
Bereich
testing-qa
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.