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查询是否返回了预期的结果

问题是如何轻松填充本地数据库以测试我们方法的结果?

  • 一种显而易见的方法是使用 代码。但是我担心这个测试的可读性会很低
  • 我想到的另一个想法是从我们的数据库中转储一个数据库 测试平台,使用它设置测试,然后仅对 检查结果
你还能想到别的吗?如何编写一个易于团队遵循的可维护测试套件

编辑:

  • 邮报 暗示

如果您没有使用特定于数据库的功能,例如特定于Oracle的自定义SQL函数,则可以在
@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”、新配置文件(。。