我使用Spring的@Configurable在Dropwizard应用程序中自动连接一个用'new'构造的bean。我有一个集成测试,使用DropwizardAppRule来启动应用程序,并使用aspectj-maven-plugin进行编译时编织。
当我从IDEA构建并运行集成测试时,bean按预期连接并且测试通过。
当我运行'mvn clean install'时,bean没有连接,测试失败,出现NullPointerException。
当我运行'mvn clean install -DskipTests'并启动应用程序时,bean已正确连接。
我的问题是为什么在'mvn clean install'期间失败?
aspectj-maven-plugin在流程源阶段运行,因此应该在集成测试运行之前对类进行检测:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
如果我反编译这个类,我可以看到它确实被插装了。
如果我在@Autowired setter中设置断点并从IDEA运行集成测试,我可以看到类正在被Spring连接。
当运行'mvn clean install'时,setter不会中断。
用@Resource代替@Autowired是没有用的。
我有一个Spring配置类,有@EnableSpringConfigured。我最好的猜测是DropwizardAppRule没有使用正确的Spring配置,尽管其他Spring组件正在正确管理。
非常感谢任何帮助。谢谢你。
编辑
我还测试了默认的surefire (maven 3.2.5)和:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
</plugin>
我明白了,但是需要更多的上下文来解释这个问题。@Configurable在enum中被实例化,如下所示:
public enum Day {
MONDAY(new MyConfigurableObject()),
...
}
单元测试和集成测试一起运行,单元测试在spring上下文可用之前实例化枚举。由于枚举存在于静态上下文中,因此集成测试将使用未连接的枚举。
解决方案是将单元测试和集成测试分开执行。我使用maven-failsafe-plugin这样做:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<excludes>
<exclude>it/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<includes>
<include>it/**</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>