简体   繁体   English

无法使用GAE运行Spring Boot单元测试

[英]Can't run spring boot unit tests with GAE

Every time I try and run unit tests for my Google App Engine with Spring Boot project I get setup errors and I cannot seem to find a solution. 每次尝试使用Spring Boot项目为Google App Engine运行单元测试时,都会出现安装错误,而且似乎找不到解决方案。

Here is my current error: 这是我当前的错误:

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)Ljavax/servlet/ServletRegistration$Dynamic;
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:117)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)Ljavax/servlet/ServletRegistration$Dynamic;
    at org.springframework.boot.context.embedded.ServletRegistrationBean.onStartup(ServletRegistrationBean.java:189)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:205)
    at org.springframework.boot.context.embedded.jetty.ServletContextInitializerConfiguration$Initializer.callInitializers(ServletContextInitializerConfiguration.java:96)
    at org.springframework.boot.context.embedded.jetty.ServletContextInitializerConfiguration$Initializer.doStart(ServletContextInitializerConfiguration.java:85)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:120)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:784)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:294)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.initialize(JettyEmbeddedServletContainer.java:83)
    at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainer.<init>(JettyEmbeddedServletContainer.java:72)
    at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory.getJettyEmbeddedServletContainer(JettyEmbeddedServletContainerFactory.java:391)
    at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory.getEmbeddedServletContainer(JettyEmbeddedServletContainerFactory.java:135)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:129)
    ... 35 common frames omitted

Here is the relevant code (pom, base boot class, test class): https://github.com/jamesclark92/stackoverflow-code/tree/master/gae-spring-boot-unit-tests 这里是相关的代码(pom,基本启动类,测试类): https : //github.com/jamesclark92/stackoverflow-code/tree/master/gae-spring-boot-unit-tests

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>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <groupId>com.football_preds</groupId>
    <artifactId>football-preds</artifactId>

    <properties>
        <app.id>football-preds</app.id>
        <app.version>1</app.version>
        <appengine.version>1.9.28</appengine.version>
        <java.version>1.7</java.version>
        <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring.framework.version>4.2.3.RELEASE</spring.framework.version>
        <start-class>com.football_preds.controllers.BaseController</start-class>
    </properties>

    <prerequisites>
        <maven>3.1.0</maven>
    </prerequisites>

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

    <dependencies>
        <!-- App engine dependencies-->
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-1.0-sdk</artifactId>
            <version>${appengine.version}</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.objectify</groupId>
            <artifactId>objectify</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <!-- Spring dependencies-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-legacy</artifactId>
            <version>1.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- Apache libaries -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

        <!-- Joda -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.1</version>
        </dependency>


        <!-- Testing dependencies-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-labs</artifactId>
            <version>${appengine.version}</version>
            <scope>test</scope>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>com.google.appengine</groupId>-->
            <!--<artifactId>appengine-api-stubs</artifactId>-->
            <!--<version>${appengine.version}</version>-->
            <!--<scope>test</scope>-->
        <!--</dependency>-->
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-testing</artifactId>
            <version>${appengine.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>2.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.el</artifactId>
            <version>2.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <version>1.3.1.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <!-- for hot reload of the web application-->
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>3.1</version>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archiveClasses>true</archiveClasses>

                    <webResources>
                        <!-- in order to interpolate version from pom into appengine-web.xml -->
                        <resource>
                            <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                            <filtering>true</filtering>
                            <targetPath>WEB-INF</targetPath>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.google.appengine</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>${appengine.version}</version>
                <configuration>
                    <enableJarClasses>false</enableJarClasses>
                    <version>${app.version}</version>
                    <port>8009</port>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>

mvn dependency:tree mvn依赖项:树

--- maven-dependency-plugin:2.9:tree (default-cli) @ football-preds ---
com.football_preds:football-preds:war:1.0-SNAPSHOT
+- com.google.appengine:appengine-api-1.0-sdk:jar:1.9.28:compile
+- com.googlecode.objectify:objectify:jar:4.0.1:compile
|  \- com.google.guava:guava:jar:14.0.1:compile
+- javax.servlet:servlet-api:jar:2.5:provided
+- org.springframework.boot:spring-boot-legacy:jar:1.0.2.RELEASE:compile
+- org.springframework.boot:spring-boot-starter-web:jar:1.2.7.RELEASE:compile
|  +- org.springframework.boot:spring-boot-starter:jar:1.2.7.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot:jar:1.2.7.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.2.7.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.2.7.RELEASE:compile
|  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
|  |  |  |  \- org.slf4j:slf4j-api:jar:1.7.12:compile
|  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile
|  |  |  +- org.slf4j:log4j-over-slf4j:jar:1.7.12:compile
|  |  |  \- ch.qos.logback:logback-classic:jar:1.1.3:compile
|  |  |     \- ch.qos.logback:logback-core:jar:1.1.3:compile
|  |  \- org.yaml:snakeyaml:jar:1.14:compile
|  +- com.fasterxml.jackson.core:jackson-databind:jar:2.4.6:compile
|  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.4.6:compile
|  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.4.6:compile
|  +- org.hibernate:hibernate-validator:jar:5.1.3.Final:compile
|  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
|  |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
|  |  \- com.fasterxml:classmate:jar:1.0.0:compile
|  +- org.springframework:spring-core:jar:4.1.8.RELEASE:compile
|  +- org.springframework:spring-web:jar:4.1.8.RELEASE:compile
|  \- org.springframework:spring-webmvc:jar:4.1.8.RELEASE:compile
+- org.springframework.boot:spring-boot-starter-actuator:jar:1.2.7.RELEASE:compile
|  \- org.springframework.boot:spring-boot-actuator:jar:1.2.7.RELEASE:compile
+- org.springframework.boot:spring-boot-starter-security:jar:1.2.7.RELEASE:compile
|  +- org.springframework:spring-beans:jar:4.1.8.RELEASE:compile
|  +- org.springframework:spring-context:jar:4.1.8.RELEASE:compile
|  +- org.springframework:spring-expression:jar:4.1.8.RELEASE:compile
|  +- org.springframework.security:spring-security-config:jar:3.2.8.RELEASE:compile
|  |  +- aopalliance:aopalliance:jar:1.0:compile
|  |  \- org.springframework.security:spring-security-core:jar:3.2.8.RELEASE:compile
|  +- org.springframework.security:spring-security-web:jar:3.2.8.RELEASE:compile
|  \- org.springframework:spring-aop:jar:4.1.8.RELEASE:compile
+- org.apache.commons:commons-lang3:jar:3.4:compile
+- commons-validator:commons-validator:jar:1.5.0:compile
|  +- commons-beanutils:commons-beanutils:jar:1.9.2:compile
|  +- commons-digester:commons-digester:jar:2.1:compile
|  +- commons-logging:commons-logging:jar:1.2:compile
|  \- commons-collections:commons-collections:jar:3.2.1:compile
+- commons-codec:commons-codec:jar:1.10:compile
+- joda-time:joda-time:jar:2.9.1:compile
+- junit:junit:jar:4.12:compile
|  \- org.hamcrest:hamcrest-core:jar:1.3:compile
+- org.springframework.boot:spring-boot-starter-test:jar:1.2.7.RELEASE:test
|  +- org.mockito:mockito-core:jar:1.10.19:test
|  |  \- org.objenesis:objenesis:jar:2.1:test
|  +- org.hamcrest:hamcrest-library:jar:1.3:test
|  \- org.springframework:spring-test:jar:4.1.8.RELEASE:test
+- com.google.appengine:appengine-api-labs:jar:1.9.28:test
+- com.google.appengine:appengine-testing:jar:1.9.28:test
+- javax.el:javax.el-api:jar:2.2.4:compile
+- org.glassfish.web:javax.el:jar:2.2.4:compile
\- org.springframework.boot:spring-boot-starter-jetty:jar:1.3.1.RELEASE:compile
   +- org.eclipse.jetty:jetty-servlets:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty:jetty-continuation:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty:jetty-http:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty:jetty-util:jar:9.2.13.v20150730:compile
   |  \- org.eclipse.jetty:jetty-io:jar:9.2.13.v20150730:compile
   +- org.eclipse.jetty:jetty-webapp:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty:jetty-xml:jar:9.2.13.v20150730:compile
   |  \- org.eclipse.jetty:jetty-servlet:jar:9.2.13.v20150730:compile
   |     \- org.eclipse.jetty:jetty-security:jar:9.2.13.v20150730:compile
   |        \- org.eclipse.jetty:jetty-server:jar:9.2.13.v20150730:compile
   +- org.eclipse.jetty.websocket:websocket-server:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty.websocket:websocket-common:jar:9.2.13.v20150730:compile
   |  |  \- org.eclipse.jetty.websocket:websocket-api:jar:9.2.13.v20150730:compile
   |  +- org.eclipse.jetty.websocket:websocket-client:jar:9.2.13.v20150730:compile
   |  \- org.eclipse.jetty.websocket:websocket-servlet:jar:9.2.13.v20150730:compile
   |     \- javax.servlet:javax.servlet-api:jar:3.1.0:compile
   \- org.eclipse.jetty.websocket:javax-websocket-server-impl:jar:9.2.13.v20150730:compile
      +- org.eclipse.jetty:jetty-annotations:jar:9.2.13.v20150730:compile
      |  +- org.eclipse.jetty:jetty-plus:jar:9.2.13.v20150730:compile
      |  |  \- org.eclipse.jetty:jetty-jndi:jar:9.2.13.v20150730:compile
      |  +- javax.annotation:javax.annotation-api:jar:1.2:compile
      |  +- org.ow2.asm:asm:jar:5.0.1:compile
      |  \- org.ow2.asm:asm-commons:jar:5.0.1:compile
      |     \- org.ow2.asm:asm-tree:jar:5.0.1:compile
      +- org.eclipse.jetty.websocket:javax-websocket-client-impl:jar:9.2.13.v20150730:compile
      \- javax.websocket:javax.websocket-api:jar:1.0:compile

Evidently you need Servlet 3.1 (credit to chrylis ). 显然,您需要Servlet 3.1(提供给chrylis )。 However, GAE only supports up to 2.5. 但是,GAE仅支持2.5。 So I have changed my pom.xml to switch between the two depending on profile. 因此,我已经更改了pom.xml,以根据配置文件在两者之间切换。

Furthermore I couldn't get the tests to work with jetty (which GAE uses for its local dev server) so I also switch to tomcat for the tests. 此外,我无法使测试与码头(GAE用于其本地开发服务器的码头)一起使用,因此我也切换到了tomcat进行测试。

pom.xml change: pom.xml更改:

<profiles>
    <profile>
        <id>build</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </profile>

    <profile>
        <id>test</id>
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    </profile>
</profiles>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM