spring-boot - Spring Boot:单元测试存储库方法的最佳策略是什么?
问题描述
我们有很多带有连接和提取的方法,如下所示:
@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 查询是否返回了预期的结果。
问题是我怎样才能轻松地填充我的本地数据库来测试我们方法的结果?
- 一种明显的方法是使用代码在测试设置中创建实体。但是恐怕这个测试的可读性会很低。
- 我想到的另一个想法是从我们的测试平台转储一个数据库,用它来设置测试,然后只运行查询来检查结果。
你能想到别的吗?我如何编写一个易于团队遵循的可维护测试套件?
编辑:
- 使用 JUnit 执行插入的帖子 建议使用DBUnit
解决方案
使用存储库填充
一种可能性是在您的测试中创建记录。这就是您所说的显而易见的解决方案。对于您当前的代码,您可以执行以下操作:
@Test
public void findUserForBilling() {
repository.saveAll(Lists.newArrayList(
new User("1", "John", "Doe", "JDoe123", new Profile(..., new ProfileEntity(1, "token123"))),
new User("2", "Jane", "Doe", "TheJane", new Profile(..., new ProfileEntity(2, "token234")))));
UserBillingDTO dto = repository.findUserForBilling("1");
assertThat(dto.getId()).isEqualTo("1");
// ...
}
虽然在某些情况下您的测试数据可能会出现在某个地方,但在这种情况下,它只有几行,这只不过是通常的单元测试准备/给定场景。
请注意:在这种类型的测试中,您不是在测试您的实体映射。如果您的实体映射中存在问题,您将无法使用这些测试来判断。
使用 SQL 文件填充
另一种可能性是使用单独的 SQL 文件,例如user-dataset.sql
在src/test/resources
:
insert into user (id, firstname, lastname) values ("1", "John", "Doe");
insert into user (id, firstname, lastname) values ("2", "Jane", "Doe");
--- ...
然后您可以使用@Sql
注释将该数据集包含在您的测试中,例如:
@RunWith(SpringRunner.class)
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Sql("classpath:user-dataset.sql") // Add this
public class UserRepositoryTest {
// ...
}
您可以将@Sql
注释添加到您的测试类,甚至是单个测试方法,例如:
@Test
@Sql("classpath:user-dataset.sql") // Add this
public void findUserForBilling() {
UserBillingDTO dto = repository.findUserForBilling("1");
assertThat(dto.getId()).isEqualTo("1");
// ...
}
请注意:如果我没记错的话,Spring 将为测试类创建一次数据源。如果您为每个测试方法执行数据集,则必须先添加一条
delete
语句以删除所有现有记录。
如果您只想为所有测试使用一个数据集,您甚至可以进一步简化并命名您的数据集data.sql
。由于如果您使用的是内存数据库(这可能对您的测试有用),Spring boot 将自动data.sql
在您的类路径上执行一个文件,因此您甚至不需要@Sql
注释。
使用 DbUnit 填充
另一种方法是选择像DbUnit这样的框架,它允许您以 XML 格式定义数据集。您可以将它与Spring Test DBUnit结合使用,以更轻松地与 Spring 集成。
您必须记住,虽然它不像使用那么容易设置,@Sql
并且您需要了解另一种语言,即用于设置数据集的 XML 结构。
推荐阅读
- docusignapi - 从 DocuSign REST API,如何完全删除/删除模板
- sql - 获取包含 2 个状态但不仅仅是其中一个状态的所有数据:SQL 查询
- c# - Razor Html.DisplayFor() 没有选择正确的本地化资源
- java - 如何在 Spinner android 中删除多余的空格?
- powershell - 在 Asp.Net Core 2 中使用 powershell 修改 web.config
- php - PHP Curl Json 或 XML 返回到数组
- javascript - 使用 Puppeteer 选择 href 属性
- c# - 需要 Level Order Traversion 帮助,出现错误
- unity3d - 如何避免 GameObject 滚动传播到 RTSCamera 缩放
- python - 列表理解中的生成器表达式未按预期工作