Skip to content

Latest commit

 

History

History
204 lines (141 loc) · 8.54 KB

spring-test.md

File metadata and controls

204 lines (141 loc) · 8.54 KB

https://docs.spring.io/spring-framework/reference/testing.html

https://docs.spring.io/spring-boot/reference/testing/index.html

Annotations

Spring

@ActiveProfiles : Définit les profils à activer pendant les tests.

@ContextConfiguration : Sert à configurer un contexte Spring pour les tests d'intégration.

@DirtiesContext : Indique que le contexte Spring a été corrompu, ce qui provoque son éviction du cache de test et permettra d'en réinitialiser un nouveau pour le test suivant.

@DynamicPropertySource : Utile pour surcharger dynamiquement des propriétés, eg. issues d'un container dynamique. Voir article https://mkyong.com/spring-boot/spring-boot-dynamicpropertysource-example pour un cas d'usage.

SpringJUnitConfig : Annotation composée qui combine @ExtendWith(SpringExtension.class) de JUnit Jupiter avec @ContextConfiguration du Spring TestContext Framework.

@TestPropertySource : Sert à configurer les properties d'un test Spring.

Spring Batch

@SpringBatchTest : Fournit les beans JobLauncherTestUtils, JobRepositoryTestUtils, StepScopeTestExecutionListener et JobScopeTestExecutionListener.

Spring Boot

@AutoConfigureTestDatabase : Permet de reconfigurer la base de données en test. Par exemple, @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) est utile pour tenir compte d'une URL H2 mode Oracle qui serait configurée dans un test/application.properties en désactivant la base H2 mem qui s'applique par défaut.

@JdbcTest : Slice pour tester Spring JDBC à la place de @SpringBootTest. Les tests deviennent transactionnels et effectuent un rollback à la fin. Une base de données en mémoire configurée automatiquement est démarrée.

@MockBean : Ajoute un mock au contexte Spring.

@ServiceConnection : Support Spring Boot de @DynamicPropertySource. Voir article https://mkyong.com/spring-boot/spring-boot-dynamicpropertysource-example pour un cas d'usage.

@SpringBootTest : Contient @ExtendWith(SpringExtension.class) (JUnit 5), démarre tout le contexte Spring. Voir les slices (@*Test) pour démarrer un contexte partiel.

@TestComponent : Equivalent à @Component mais pour les tests. Non scanné par @SpringBootApplication, il l'est cependant par @ComponentScan.

@TestConfiguration : Configuration spécifique pour les tests Spring (cad non scanné par @SpringBootApplication). Permet d'ajouter ou redéfinir certains beans (spring.main.allow-bean-definition-overriding nécessaire).

@WebMvcTest : Slice pour tester Spring MVC à la place de @SpringBootTest. Fournit notamment un bean MockMvc.

Spring Boot TestContainers support

https://docs.spring.io/spring-boot/reference/testing/testcontainers.html

https://github.com/testcontainers/testcontainers-java-spring-boot-quickstart

Dependency

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-testcontainers</artifactId>
      <scope>test</scope>
    </dependency>

Exemples

@ContextConfiguration

@ContextConfiguration("/test-config.xml") 
class XmlApplicationContextTests {
	// class body...
}

@ContextConfiguration(classes = TestConfig.class) 
class ConfigClassApplicationContextTests {
	// class body...
}

@SpringBootTest chargeant tout le contexte applicatif, la combinaison suivante permet de tester que les @ConfigurationProperties avec Spring Boot.

import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(MaConfigProperties.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)

@TestConfiguration

// Façon 1 : configuration externe

@TestConfiguration
public class MaConfigurationDeTest {
  // beans
}

@SpringBootTest
@Import(MaConfigurationDeTest.class)
publis class MesTests {
  // tests
}

// Façon 2 : configuration en tant que classe static

@SpringBootTest
publis class MesTests {
  // tests

  @TestConfiguration
  static class MaConfigurationDeTest {
    // beans
  }

}

@TestPropertySource

@ContextConfiguration
@TestPropertySource("/test.properties") 
class MyIntegrationTests {
	// class body...
}

@ContextConfiguration
@TestPropertySource(properties = { "timezone = GMT", "port: 4242" }) 
class MyIntegrationTests {
	// class body...
}

@WebMvcTest

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(MonController.class)
public class MonControllerTest {

  @Autowired
  private MockMvc mockMvc; // bean fourni par @WebMvcTest

  @Test
  public void testHomePage() throws Exception {
    mockMvc.perform(get("/"))
          .andExpect(status().isOk())
          .andExpect(view().name("home"))
          .andExpect(content().string(containsString("Bienvenue...")));
  }
}

Bean validation unit test

https://docs.spring.io/spring-framework/reference/core/validation/beanvalidation.html#validation-beanvalidation-spring

@SpringJUnitConfig({LocalValidatorFactoryBean.class})
public class ValidatorTest {
    @Autowired
    private Validator validator;

    @Test
    void checkXXX() {
      ...
    }
}

Database support for integration test

Spring framework :

Spring Boot :

Properties validation unit test

https://docs.spring.io/spring-boot/reference/testing/test-utilities.html#testing.utilities.config-data-application-context-initializer

@SpringJUnitConfig(classes = Config.class, initializers = ConfigDataApplicationContextInitializer.class)
@EnableConfigurationProperties(MyProps.class)
class ServiceTest {
  ...
}