我已经开始了一个新项目:PostfixSQLConfig。这是一个简单的Spring Boot应用程序,本质上应该为4个简单的数据库表提供CRUD访问。我为第一个表编写了存储库,并为该存储库编写了一些基本的集成测试。由于此特定表不应提供更新功能,因此我将更新功能实现为:
@Override public void update(@NonNull Domain domain) throws NotUpdatableException { throw new NotUpdatableException("Domain entities are read-only"); }
NotUpdatableException我的自定义异常类在哪里。
NotUpdatableException
此代码的IT如下所示:
@Test(expected = NotUpdatableException.class) public void testUpdate() throws NotUpdatableException { val domain = Domain.of("test"); domainRepository.update(domain); }
如果从我的IDE(IntelliJ 2018.2 EAP)运行此测试,它将通过,但运行mvn verify失败并显示以下信息:
mvn verify
java.lang.NoClassDefFoundError: com/github/forinil/psc/exception/NotUpdatableException at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetMethodRecursive(Class.java:3048) at java.lang.Class.getMethod0(Class.java:3018) at java.lang.Class.getMethod(Class.java:1784) at org.apache.maven.surefire.util.ReflectionUtils.tryGetMethod(ReflectionUtils.java:60) at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isSuiteOnly(JUnit3TestChecker.java:65) at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isValidJUnit3Test(JUnit3TestChecker.java:60) at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.accept(JUnit3TestChecker.java:55) at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.accept(JUnit4TestChecker.java:53) at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:102) at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:309) at org.apache.maven.surefire.junit4.JUnit4Provider.setTestsToRun(JUnit4Provider.java:189) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:132) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:379) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:340) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:413) Caused by: java.lang.ClassNotFoundException: com.github.forinil.psc.exception.NotUpdatableException at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 18 more
老实说,我不知道为什么…
有人遇到过这个问题吗?
我知道了,所以我在回答自己的问题,以防其他人遇到相同的问题。
事实证明,maven-failsafe-plugin不会将target / classes目录添加到类路径,而是将生成的jar添加到大多数情况下可以正常工作。
但是,当涉及到Spring Boot时,生成的jar包含Spring Boot自定义类加载器类,而不是target / classes目录的内容,这些内容已移至目录BOOT-INF / classes。由于maven-failsafe- plugin使用“常规”类加载器,因此它仅加载Spring Boot类加载器类,因此首先会失败,因此预计将使用其中一个项目类。
为了在Spring Boot项目中运行IT测试,必须从依赖项中排除打包的jar,然后添加原始的,未修改的jar或target / classes目录,这就是我所做的。
maven-failsafe-plugin和Spring Boot的正确配置是:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.21.0</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <classpathDependencyExcludes> <classpathDependencyExcludes>${groupId}:${artifactId}</classpathDependencyExcludes> </classpathDependencyExcludes> <additionalClasspathElements> <additionalClasspathElement>${project.build.outputDirectory}</additionalClasspathElement> </additionalClasspathElements> </configuration> </plugin>