应用程序(src / main)运行时,文件是否在类路径的src / test / resources中?

时间:2019-08-15 10:43:58

标签: java spring-boot

新手在这里! 我在SO上发现了很多类似的问题,但没有一个给我一个僵硬的答案。

我为spring-boot应用程序中的所有层(包括持久层)编写了测试。为了测试持久层,我使用了H2数据库。我使用@DataJpaTest批注,并将schema.sql和data.sql脚本放置到src / test / resources / db文件夹中,以创建模式并使用data.sql中的数据填充它。而且效果很好,所有测试都使用该数据通过。

现在我要尝试的是使用@SpringBootTest设置集成测试以测试整个应用程序-从上至下,从Web层到数据层。我使用H2配置创建了一个application-test.properties,并使用@ActiveProfiles(“ test”)注释了我的测试类,它工作正常。当我运行此测试类时,应用程序上下文将启动,H2也将启动,但是当然那里没有数据。我想使用来自src / test / resources / db的data.sql中的相同日期填充内存数据库。

我以这种方式修改了application-test.properties: spring.datasource.url = jdbc:h2:mem:testdb; INIT = RUNSCRIPT FROM'classpath:db / schema.sql'\; RUNSCRIPT FROM'classpath:db / data.sql' 我得到了org.h2.jdbc.JdbcSQLNonTransientException:IO异常:“ java.io.FileNotFoundException:资源/db/schema.sql”异常。

我做了很多谷歌搜索,发现更多的资源说src / main / resources和src / test / resources都在类路径上。如果是这样,为什么我会得到这个例外?

此外,当我将这两个脚本放入src / main / resources / db时,它可以正常工作。另外,无论我的持久性层测试在src / main / resources / db还是src / test / resources / db中,这些脚本都可以正常运行。因此,它看起来像一个同时使用src / main / resources和src / test / resources位置作为类路径的测试环境,但是该环境仅使用src / main / resources作为类路径!会是真的吗?

我尝试过的一种可能的解决方案,它的工作是不运行那些脚本(从.properties文件中删除INIT = RUNSCRIPT从'classpath:db / schema.sql'\; RUNSCRIPT从'classpath:db / data.sql'从)并且在测试之前以编程方式创建一些对象并将其持久保存到数据库中,然后编写测试,但是我认为,从脚本中填充数据比在每个测试类中编写此代码要容易得多,也更精简。

另一种可能的解决方案是将这些脚本从src / test / resources / db复制到src / main / resources / db,但这意味着我会重复数据,并且我讨厌这样做。而且,这意味着更难维护。

下一个可能的解决方案是将这些脚本放入src / main / resources / db中,因为正如我所说,无论这些脚本位于src / main / resources / db还是src / test /中,数据持久性测试都能正常工作资源/ db。但是,这些脚本与测试有关,所以我认为它们不属于应用程序的主要部分。

而且,如果我提供了这些脚本的绝对路径,则可以正常工作,但这意味着我的团队成员必须对其进行修改以适合其计算机。并不是真正的最佳解决方案。

所以,我的问题是: 1.测试环境是否同时使用src / main / resources和src / test / resources位置作为类路径,但是主环境仅使用src / main / resources作为类路径? 2.我该如何解决这个挑战?

1 个答案:

答案 0 :(得分:1)

  

测试环境是否同时使用src/main/resourcessrc/test/resources位置作为类路径,但是主环境仅使用src/main/resources作为类路径?

是的。是真的。在Maven和Gradle中,test的类路径都继承自main,反之亦然。这意味着src/main/javasrc/main/resources的类和资源在测试执行期间可用,但是src/test/javasrc/test/resources不能被主要代码库访问。还要注意,测试类和资源不是可传递的,即它们在依赖的项目中不可用。

  

我该如何解决这一挑战?

嗯,有很多解决方案:

  1. 将资源放在src/main中(显然)
  2. 将两个位置所需的资源提取到一个单独的模块中并依靠它。
  3. 使用maven-resources-plugin从其他位置复制文件。