Spring boot SpringBoot:单元测试存储库方法的最佳策略是什么?
我们有很多具有连接和获取的方法,它们看起来像:Spring boot SpringBoot:单元测试存储库方法的最佳策略是什么?,spring-boot,testing,hql,spring-repositories,Spring Boot,Testing,Hql,Spring Repositories,我们有很多具有连接和获取的方法,它们看起来像: @Query( "select new com.company.user.entity.DTO.UserBillingDTO(" + "u.id as id, " + "u.firstName as firstName, " + "u.lastName as lastName, " +
@Query(
"select new com.company.user.entity.DTO.UserBillingDTO(" +
"u.id as id, " +
"u.firstName as firstName, " +
"u.lastName as lastName, " +
"e.tokenId as tokenId," +
"u.companyId as companyId," +
"e.id as entityId, " +
"u.userName as userName, " +
"u.locale as locale) " +
"from User as u " +
"join u.profiles as p " +
"join p.entity as e " +
"where u.id = :userId")
UserBillingDTO findUserForBilling(@Param("userId") String userId);
我想通过测试来介绍这些方法,看看我们的HQL查询是否返回了预期的结果
问题是如何轻松填充本地数据库以测试我们方法的结果?
- 一种显而易见的方法是使用 代码。但是我担心这个测试的可读性会很低
- 我想到的另一个想法是从我们的数据库中转储一个数据库 测试平台,使用它设置测试,然后仅对 检查结果
- 邮报 暗示
@SpringBootTest
测试中设置嵌入式数据库。用注释注释测试类,例如用嵌入式内存数据库替换默认应用程序DataSource
bean:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
您可以使用Flyway或Liquibase按照章节填充数据库。根据文件:
您还可以使用Flyway为特定场景提供数据。例如,您可以将特定于测试的迁移放在src/test/resources中,并且它们仅在应用程序开始测试时运行。此外,您还可以使用特定于配置文件的配置自定义spring.flyway.locations,以便某些迁移仅在特定配置文件处于活动状态时运行。例如,在application-dev.properties中,可以指定以下设置:
如果未使用特定于数据库的功能,例如特定于Oracle的自定义SQL函数,则可以在
@springbootest
测试中设置嵌入式数据库。用注释注释测试类,例如用嵌入式内存数据库替换默认应用程序DataSource
bean:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
您可以使用Flyway或Liquibase按照章节填充数据库。根据文件:
您还可以使用Flyway为特定场景提供数据。例如,您可以将特定于测试的迁移放在src/test/resources中,并且它们仅在应用程序开始测试时运行。此外,您还可以使用特定于配置文件的配置自定义spring.flyway.locations,以便某些迁移仅在特定配置文件处于活动状态时运行。例如,在application-dev.properties中,可以指定以下设置:
使用存储库填充
一种可能是在测试中创建记录。这就是您所描述的显而易见的解决方案。对于当前代码,可以执行以下操作:
@测试
公共无效FindUserFilling(){
repository.saveAll(Lists.newArrayList(
新用户(“1”、“John”、“Doe”、“JDoe123”、新配置文件(…、新配置文件实体(1,“token123”)),
新用户(“2”、“Jane”、“Doe”、“TheJane”、新配置文件(…、新配置文件实体(2,“token234”));
UserBillingDTO dto=repository.findUserForBilling(“1”);
断言(dto.getId()).isEqualTo(“1”);
// ...
}
虽然在某些情况下,您的测试数据可能会出现在某些地方,但在这种情况下,它只是几行,这只不过是一个普通的单元测试准备/给定场景
请注意:在这种类型的测试中,您没有测试实体映射。如果实体映射中存在问题,您将无法使用这些测试来判断
使用SQL文件填充
另一种可能是在src/test/resources
中使用单独的SQL文件,例如user dataset.SQL
:
插入用户(id、firstname、lastname)值(“1”、“John”、“Doe”);
在用户(id、firstname、lastname)值中插入(“2”、“Jane”、“Doe”);
--- ...
然后,您可以使用@Sql
注释将该数据集包括在测试中,例如:
@RunWith(SpringRunner.class)
@DataJpaTest
@事务性(传播=传播。不受支持)
@Sql(“classpath:user-dataset.Sql”)//添加此
公共类UserRepositoryTest{
// ...
}
您可以将@Sql
注释添加到测试类,甚至添加到单个测试方法,例如:
@测试
@Sql(“classpath:user-dataset.Sql”)//添加此
公共无效FindUserFilling(){
UserBillingDTO dto=repository.findUserForBilling(“1”);
断言(dto.getId()).isEqualTo(“1”);
// ...
}
请注意:如果我没有弄错的话,Spring将为测试类创建一次数据源。如果为每个测试方法执行数据集,则必须先添加delete
语句来删除所有现有记录
如果所有测试只需要一个数据集,则可以进一步简化并将数据集命名为data.sql
。由于Spring boot将自动在类路径上执行data.sql
文件,如果您使用的是内存中的数据库(这可能对您的测试有用),因此您甚至不需要@sql
注释
使用DbUnit填充
另一种方法是选择类似的框架,它允许您以XML格式定义数据集。您可以将其与结合使用,以便更轻松地与Spring集成
但是,您必须记住,它不像使用@Sql
那样容易设置,您需要了解另一种语言,即用于设置数据集的XML结构。使用存储库填充
一种可能是在测试中创建记录。这就是您所描述的显而易见的解决方案。对于当前代码,可以执行以下操作:
@测试
公共无效FindUserFilling(){
repository.saveAll(Lists.newArrayList(
新用户(“1”、“John”、“Doe”、“JDoe123”、新配置文件(。。