2014-06-07 5 views
11

Ich versuche, den Spring-Security-Hauptanmeldungsprozess zu testen, indem ich einen Testcontainer in Spring Boot starte, wobei ich denke, was sie vorschlagen. HierSpring Boot Testing: EmbeddedWebApplicationContext konnte aufgrund fehlender EmbeddedServletContainerFactory-Bean nicht gestartet werden

ist die Maven pom:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.touchcorp.xxxxx</groupId> 
    <artifactId>xxxxx-lc</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.0.2.RELEASE</version> 
    </parent> 

<properties> 
    <java.version>1.7</java.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-jpa</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-security</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-thymeleaf</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-test</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>commons-dbcp</groupId> 
     <artifactId>commons-dbcp</artifactId> 
     <version>1.4</version> 
    </dependency> 
    <dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>5.1.25</version> 
    </dependency> 

    <!-- Gateway --> 
    <dependency> 
     <groupId>org.jdom</groupId> 
     <artifactId>jdom</artifactId> 
     <version>2.0.2</version> 
    </dependency> 
    <dependency> 
     <groupId>jaxen</groupId> 
     <artifactId>jaxen</artifactId> 
     <version>1.1.4</version> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.resteasy</groupId> 
     <artifactId>resteasy-jaxrs</artifactId> 
     <version>2.3.5.Final</version> 
    </dependency> 
    <!-- Hashing--> 
    <dependency> 
     <groupId>com.google.guava</groupId> 
     <artifactId>guava</artifactId> 
     <version>17.0</version> 
    </dependency> 

</dependencies> 

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> 
     </plugin> 
    </plugins> 
</build> 
</project> 

Mein Test Anwendungskontext:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = {MvcConfig.class,SecurityConfig.class}) 
@WebAppConfiguration 
@EnableAutoConfiguration 
@IntegrationTest 
public class TestApplicationContext { 

    @Bean 
    public EmbeddedServletContainerFactory servletContainer() { 
     TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); 
     factory.setPort(9000); 
     factory.setSessionTimeout(10, TimeUnit.MINUTES); 
     //factory.addErrorPages(new ErrorPage(HttpStatus.404, "/notfound.html")); 
     return factory; 
    } 

} 

und hier ist der spezifische Test:

@RunWith(SpringJUnit4ClassRunner.class) 
public class ApplicationIntegrationTest extends TestApplicationContext { 

    MockMvc mockMvc; 

    @Autowired 
    private WebApplicationContext wac; 

    @Resource(name="springSecurityFilterChain") 
    private FilterChainProxy springSecurityFilterChain; 


    @Before 
    public void setup() { 
     mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilter(springSecurityFilterChain).build(); 

    } 

    @Test 
     public void thatViewBootstrapUsesHttpNotFound() throws Exception { 


     MvcResult result = mockMvc.perform(post("/login") 
      .param("username", "user").param("password", "password")).andReturn(); 
     Cookie c = result.getResponse().getCookie("my-cookie"); 
     assertThat(c.getValue().length(), greaterThan(10)); 

     // No cookie; 401 Unauthorized 
     mockMvc.perform(get("/")).andExpect(status().isUnauthorized()); 

     // With cookie; 200 OK 
     mockMvc.perform(get("/").cookie(c)).andExpect(status().isOk()); 

     // Logout, and ensure we're told to wipe the cookie 
     result = mockMvc.perform(delete("/session")).andReturn(); 
     c = result.getResponse().getCookie("my-cookie"); 
     assertThat(c.getValue().length(), is(0)); 
     } 

} 

und hier ist der Fehler:

java.lang.IllegalStateException: Failed to load ApplicationContext 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) 
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:135) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) 
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:88) 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64) 
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91) 
    ... 28 more 
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:185) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:158) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132) 
    ... 35 more 

Wie Sie sehen können, habe ich versucht, den Container in der Config anzugeben, aber das scheint nicht zu funktionieren. Kann mir jemand sagen, was ich vermisse?

dank

Antwort

6

Sie die Einstellung der Container in einer Config-Klasse eigentlich nicht auf, sind Sie in der Testklasse zu tun. Verschiebe das @Bean zu einem @Configuration und du hast vielleicht mehr Glück.

+2

Das war es. Ich habe die @IntegrationTest Annotation aus TestApplicationContext entfernt und es ging weg. Vielen Dank. –

+0

Hallo Michael, kannst du ausrechnen, ob das Entfernen von "@IntegrationTest" aus TestApplicationContext funktioniert (weil es bei mir nicht funktioniert, wenn ich das selbe Problem habe - ich will einen eingebetteten Container nur für Tests) und wenn du meinst @ Daves Vorschlag musste auch verwendet werden, dann ersetzt das Ersetzen von "@Bean" durch "@Configuration" in Ihrem Beispiel Kompilierungsfehler, die angeben, dass "@Configuration" dort nicht erlaubt ist. Alle Hinweise, die Sie geben können, sind sehr hilfreich. Danke, Paddy – Paddy

+0

Einfach eine Anmerkung durch eine andere zu ersetzen, wird nicht helfen. Eine '@ Bean' ist eine Methode. Fügen Sie eine Klasse hinzu und notieren Sie sie "@ Konfiguration" und setzen Sie die Container-Factory dort als '@ Bean' ein und fügen Sie die Klasse dann zu Ihrem Anwendungskontext hinzu. Kopieren Sie den Code nicht vom OP (es ist ein Durcheinander). –

Verwandte Themen