Spring Cloud Contract生产者流:运行ContractsTest时抛出FileNotFoundException
你遇到的问题是ContractsTest和对应的yml文件在同一目录,但运行测试时testClass.getClass().getResource(relativePath)返回null,导致找不到文件抛出异常,堆栈信息如下:
java.lang.IllegalStateException: java.io.FileNotFoundException: test_status_tracking_update.yml at org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.fileToBytes(ContractVerifierUtil.java:83) at org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.contract(ContractVerifierUtil.java:136) at de.test.bla.test.cdc.base.ContractsTest.validate_test_status_tracking_update(ContractsTest.java:26)
下面是几个排查和解决方向:
调整资源文件的存放路径或构建配置
Maven/Gradle默认只会把src/main/resources、src/test/resources下的文件打包到classpath。如果你的yml文件放在测试类同目录(比如src/test/java下的包路径里),默认不会被编译复制到classpath对应的目录。
解决办法二选一:- 把yml文件移到
src/test/resources下,保持和测试类对应的包结构(比如src/test/resources/de/test/bla/test/cdc/base/) - 修改构建脚本,让测试类目录下的yml文件也被复制:
Maven(pom.xml):
Gradle(build.gradle):<build> <testResources> <testResource> <directory>src/test/java</directory> <includes> <include>**/*.yml</include> </includes> </testResource> </testResources> </build>sourceSets { test { resources { srcDirs = ['src/test/java', 'src/test/resources'] includes = ['**/*.yml'] } } }
- 把yml文件移到
修正getResource的调用方式
testClass.getClass().getResource(relativePath)是从classpath根路径查找文件,而不是测试类所在的目录。如果文件和测试类在同一包下,改用testClass.getResource(relativePath)(不带getClass()),或者使用带包路径的绝对路径(开头加斜杠),比如/de/test/bla/test/cdc/base/test_status_tracking_update.yml,也可以用相对路径./test_status_tracking_update.yml。检查IDE编译输出
确认IDE(比如IntelliJ)是否把yml文件复制到了测试编译输出目录(比如target/test-classes或build/classes/test)。如果没复制,手动执行mvn test-compile(Maven)或gradle testClasses(Gradle)触发编译同步。核对文件名大小写
注意Linux等大小写敏感的系统,代码里写的文件名要和实际文件完全一致,包括大小写,别出现拼写或大小写错误。
内容的提问来源于stack exchange,提问作者Wash

