Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Author:  Oleksandr_Dekin

...

  1. Download DockerToolbox-19.03.1.exe from https://github.com/docker/toolbox/releases/tag/v19.03.1
  2. Follow instruction:  http://docs.docker.oeynet.com/toolbox/toolbox_install_windows
  3. During installation unselect component VirtualBox Follow http://docs.docker.oeynet.com/toolbox/toolbox_install_windows
    NOTE: you don't need to install VirtualBox if you have installed before it (for example: you are working with vagrant and use VB)
  4. Restarting windows is important, because it will not be able to find docker in Path (even if you add manually)
  5. After install, on you desktop will be created shortcut shortcut for docker - Docker Quickstart Terminal

...

  • Integration test with JUnit 4.12 and Spring Boot < 2.2.6


    Code Block
    languagejava
    titleUsing: JUnit 4.12 and Spring Boot < 2.2.6
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @ContextConfiguration(initializers = IntegrationTest.Initializer.class)
    public class ApplicationIT {
    
        @ClassRule
        public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer().withPassword("inmemory")
                .withUsername("inmemory");
    
        public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
            @Override
            public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
                TestPropertyValues values = TestPropertyValues.of(
                        "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
                        "spring.datasource.password=" + postgreSQLContainer.getPassword(),
                        "spring.datasource.username=" + postgreSQLContainer.getUsername()
                );
                values.applyTo(configurableApplicationContext);
            }
        }
    
        @Ŧest
        public void contextLoads() {
        }
    }


  • Integration test with JUnit 5 and Spring Boot < 2.2.6

    If your application makes use of JUnit 5 but is using a Spring Boot version < 2.2.6, you don't have access to the @DynamicPropertySource feature.
    A possible integration test to verify a REST API endpoint is working as expected looks like the following:

    Code Block
    languagejava
    titleJUnit 5 example with Spring Boot < 2.2.6
    // JUnit 5 example with Spring Boot < 2.2.6
    @Testcontainers
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    @ContextConfiguration(initializers = DeletePersonIT.Initializer.class)
    public class DeletePersonIT {
     
      @Container
      public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
        .withPassword("inmemory")
        .withUsername("inmemory");
     
      @Autowired
      private PersonRepository personRepository;
     
      @Autowired
      public TestRestTemplate testRestTemplate;
     
      public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
     
        @Override
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
          TestPropertyValues values = TestPropertyValues.of(
            "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
            "spring.datasource.password=" + postgreSQLContainer.getPassword(),
            "spring.datasource.username=" + postgreSQLContainer.getUsername()
          );
          values.applyTo(configurableApplicationContext);
        }
      }
     
      @Test
      @Sql("/testdata/FILL_FOUR_PERSONS.sql")
      public void testDeletePerson() {
        testRestTemplate.delete("/api/persons/1");
        assertEquals(3, personRepository.findAll().size());
        assertFalse(personRepository.findAll().contains("Phil"));
     
      }
    }


  • Basic application integration test with JUnit 5 and Spring Boot >= 2.2.6

    If your application uses JUnit 5, you can't use the @ClassRule anymore. Fortunately, Testcontainers provides a solution to write tests with JUnit Jupiter:

    Code Block
    languagejava
    titlejunit-jupiter
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>${testcontainers.version}</version>
      <scope>test</scope>
    </dependency>

    With this dependency and a more recent version of Spring Boot (> 2.2.6) the basic integration test looks like the following:

    Code Block
    languagejava
    titleJUnit 5 example with Spring Boot >= 2.2.6
    // JUnit 5 example with Spring Boot >= 2.2.6
    @Testcontainers
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class ApplicationIT {
     
      @Container
      public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
        .withPassword("inmemory")
        .withUsername("inmemory");
     
      @DynamicPropertySource
      static void postgresqlProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
        registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
        registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
      }
     
      @Test
      public void contextLoads() {
      }
    }


...

  • Now, we can extend and write test:

    Code Block
    languagejava
    titleFooControllerIT
    collapsetrue
    @Log4j2
    class FooControllerIT extends BaseIntegrationTest {
    
      @Test
      void testFoo() throws Exception {
        //...
      }
      
      //...
    }


NOTE: @DirtiesContext - SpringBootTest is reusing Spring context between tests so there is a common Hikari Pool between tests. But in the background testcontainers killed (after the previous test) a container and created a new one (before the next test). SpringBootTest is not aware of that change resulting in a new Postgres container so Hikari Pool is the same as in the previous test (pointing to already used and currently unavailable port). For reusing testcontainers we can add annotation @DirtiesContext

...