WebAppConfiguration in Frühlingstests

1. Übersicht

In diesem Artikel werden wir die Annotation @WebAppConfiguration im Frühjahr untersuchen, warum wir sie in unseren Integrationstests benötigen und wie wir sie so konfigurieren können, dass diese Tests tatsächlich einen WebApplicationContext booten .

2. @WebAppConfiguration

Einfach ausgedrückt ist dies eine Annotation auf Klassenebene, mit der eine Webversion des Anwendungskontexts im Spring Framework erstellt wird.

Es wird verwendet, um anzugeben, dass der ApplicationContext, der für den Test gebootet wird , eine Instanz von WebApplicationContext sein sollte .

Ein kurzer Hinweis zur Verwendung - diese Anmerkung finden wir normalerweise in Integrationstests, da der WebApplicationContext zum Erstellen eines MockMvc- Objekts verwendet wird. Weitere Informationen zu Integrationstests mit Spring finden Sie hier.

3. Laden eines WebApplicationContext

Ab Spring 3.2 wird jetzt das Laden eines WebApplicationContext in Integrationstests unterstützt:

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

Dies weist das TestContext- Framework an, dass ein WebApplicationContext für den Test geladen werden soll.

Und im Hintergrund ein MockServletContext erstellt und an unseren Test des mitgelieferten WebApplicationContext durch den Testcontext Rahmen.

3.1. Einstellmöglichkeiten

Standardmäßig wird der Basisressourcenpfad für den WebApplicationContext auf "file: src / main / webapp" festgelegt. Dies ist der Standardspeicherort für das Stammverzeichnis der WAR in einem Maven-Projekt.

Wir können dies jedoch überschreiben, indem wir einfach einen alternativen Pfad zur Annotation @WebAppConfiguration angeben :

@WebAppConfiguration("src/test/webapp")

Wir können anstelle des Dateisystems auch auf einen Basisressourcenpfad aus dem Klassenpfad verweisen:

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

3.2. Caching

Sobald der WebApplicationContext geladen ist, wird er zwischengespeichert und für alle nachfolgenden Tests wiederverwendet, die dieselbe eindeutige Kontextkonfiguration innerhalb derselben Testsuite deklarieren.

Weitere Informationen zum Zwischenspeichern finden Sie im Abschnitt Kontext-Zwischenspeichern des Referenzhandbuchs.

4. Verwenden von @WebAppConfiguration in Tests

Nachdem wir verstanden haben, warum wir die Annotation @WebAppConfiguration in unseren Testklassen hinzufügen müssen, wollen wir sehen, was passiert, wenn wir sie bei Verwendung eines WebApplicationContext nicht hinzufügen .

@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(); } ... }

Beachten Sie, dass wir die Anmerkung auskommentiert haben, um das Szenario zu simulieren, in dem wir vergessen haben, sie hinzuzufügen. Hier ist leicht zu erkennen, warum der Test fehlschlägt, wenn wir den JUnit-Test ausführen: Wir versuchen, den WebApplicationContext in einer Klasse automatisch zu verdrahten, in der wir keinen festgelegt haben .

Ein typischeres Beispiel ist jedoch ein Test, der eine webfähige Spring-Konfiguration verwendet. Das ist eigentlich genug, um die Testpause zu machen.

Werfen wir einen Blick:

@RunWith(SpringJUnit4ClassRunner.class) // @WebAppConfiguration omitted on purpose @ContextConfiguration(classes = WebConfig.class) public class EmployeeTestWithoutMockMvc { @Autowired private EmployeeController employeeController; ... }

Auch wenn das obige Beispiel einen WebApplicationContext nicht automatisch verdrahtet , schlägt er dennoch fehl, da versucht wird, eine webfähige Konfiguration zu verwenden - WebConfig :

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

Die Annotation @EnableWebMvc ist hier der Schuldige - für die im Grunde ein webfähiger Spring-Kontext erforderlich ist, und ohne diesen wird der Test fehlschlagen:

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

Das ist also das Problem, das wir leicht beheben können, indem wir unseren Tests die Annotation @WebAppConfiguration hinzufügen .

5. Schlussfolgerung

In diesem Artikel haben wir gezeigt, wie wir das TestContext- Framework einen WebApplicationContext in unsere Integrationstests laden lassen können, indem wir einfach die Anmerkung hinzufügen.

Schließlich haben wir uns die Beispiele angesehen, die zwar die @ ContextConfiguration zum Test hinzufügen , dies jedoch nur funktionieren kann, wenn wir die Annotation @WebAppConfiguration hinzufügen .

Die Implementierung der Beispiele in diesem Artikel finden Sie in unserem Repository auf GitHub.