WebAppConfiguration dans les tests de printemps

WebAppConfiguration dans les tests de printemps

1. Vue d'ensemble

Dans cet article, nous allons explorer l'annotation@WebAppConfiguration dans Spring, pourquoi nous en avons besoin dans nos tests d'intégration et aussi comment la configurer pour que ces tests amorcent réellement unWebApplicationContext.

2. @WebAppConfiguration

En termes simples, il s’agit d’une annotation au niveau classe utilisée pour créer une version Web du contexte de l’application dans Spring Framework.

Il est utilisé pour indiquer que leApplicationContext qui est amorcé pour le test doit être une instance deWebApplicationContext.

Une note rapide sur l'utilisation - nous trouverons généralement cette annotation dans les tests d'intégration car leWebApplicationContext est utilisé pour construire un objetMockMvc. Vous pouvez trouver plus d'informations sur les tests d'intégration avec Springhere.

3. Chargement d'unWebApplicationContext

À partir de Spring 3.2, il existe désormais un support pour le chargement d'unWebApplicationContext dans les tests d'intégration:

@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeControllerTest {
    ...
}

Cela indique au frameworkTestContext qu'unWebApplicationContext doit être chargé pour le test.

Et, en arrière-plan, unMockServletContext est créé et fourni auxWebApplicationContext de notre test par le frameworkTestContext.

3.1. Options de configuration

Par défaut, le chemin d'accès aux ressources de base pour lesWebApplicationContext sera défini sur“file:src/main/webapp”,, qui est l'emplacement par défaut de la racine du WAR dans un projet Maven.

Cependant, nous pouvons remplacer cela en fournissant simplement un chemin alternatif à l'annotation@WebAppConfiguration:

@WebAppConfiguration("src/test/webapp")

Nous pouvons également référencer un chemin de ressource de base à partir du chemin de classe au lieu du système de fichiers:

@WebAppConfiguration("classpath:test-web-resources")

3.2. Mise en cache

Une fois leWebApplicationContext chargé, il sera mis en cache et réutilisé pour tous les tests suivants qui déclarent la même configuration de contexte unique dans la même suite de tests.

Pour plus de détails sur la mise en cache, vous pouvez consulter la sectionContext caching du manuel de référence.

4. Utilisation de@WebAppConfiguration dans les tests

Maintenant que nous comprenons pourquoi nous devons ajouter l'annotation@WebAppConfiguration dans nos classes de test, voyonswhat happens if we miss adding it lorsque nous utilisons unWebApplicationContext.

@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTest {

    @Autowired
    private WebApplicationContext webAppContext;
    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
    }

    ...
}

Notez que nous avons commenté l'annotation pour simuler le scénario dans lequel nous avons oublié de l'ajouter. Ici, il est facile de voir pourquoi le test échoue lorsque nous exécutons le test JUnit:we are trying to autowire the WebApplicationContext in a class where we haven’t set one.

Un exemple plus typique est cependant un test qui utilise une configuration Spring activée pour le Web; c’est en fait suffisant pour interrompre le test.

Regardons:

@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTestWithoutMockMvc {

    @Autowired
    private EmployeeController employeeController;

    ...
}

Même si l'exemple ci-dessus ne lance pas automatiquement unWebApplicationContext, il échouera toujours car il essaie d'utiliser une configuration Web -WebConfig:

@Configuration
@EnableWebMvc
@ComponentScan("com.example.web")
public class WebConfig implements WebMvcConfigurer {
    ...
}

L'annotation@EnableWebMvc est le coupable ici - qui nécessitera essentiellement un contexte Spring compatible Web, et sans elle - nous verrons le test échouer:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
  No qualifying bean of type [javax.servlet.ServletContext] found for dependency:
    expected at least 1 bean which qualifies as autowire candidate for this dependency.

Dependency annotations:
  {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at o.s.b.f.s.DefaultListableBeanFactory
      .raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
    at o.s.b.f.s.DefaultListableBeanFactory
      .doResolveDependency(DefaultListableBeanFactory.java:1119)
    at o.s.b.f.s.DefaultListableBeanFactory
      .resolveDependency(DefaultListableBeanFactory.java:1014)
    at o.s.b.f.a.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
      .inject(AutowiredAnnotationBeanPostProcessor.java:545)
    ... 43 more

C'est donc le problème que nous résolvons facilement en ajoutant l'annotation@WebAppConfiguration à nos tests.

5. Conclusion

Dans cet article, nous avons montré comment nous pouvons laisser le frameworkTestContext charger unWebApplicationContext dans nos tests d'intégration simplement en ajoutant l'annotation.

Enfin, nous avons examiné les exemples selon lesquels même si nous ajoutons les @ContextConfiguration au test, cela ne pourra pas fonctionner à moins que nous ajoutions l'annotation@WebAppConfiguration.

L'implémentation des exemples de cet article est disponible dans notre référentiel surGitHub.