单元测试如何在spring中插入记录(没有删除方法)

How unit test insert record in spring (no delete method)

我有 DAO 使用 Spring 的 jdbcTemplate 和创建读取更新(无删除)操作。

Create 方法有 ID 参数,它是 table 中的唯一键。

除了模拟 DAO,我如何在不违反约束的情况下实际测试创建?

使用随机ID有时还是会失败

我是否应该覆盖 setAutoCommit 以避免添加记录?它仍然被视为有效的单元测试吗?

我是否必须事先删除 SQL 数据库中的记录,或者是否有针对此类测试的 spring 选项?

或者我应该将其视为集成测试而不是单元测试?

编辑

我正在使用 Oracle,我无法使用序列为 ID 创建值

我们在生产中存在一些数据源(不用于测试)

这真的取决于这样一个测试的目的是什么,并不是所有的测试都是"unit tests"这方面的。

例如,如果目标是测试封装业务逻辑的 "service",但从该服务有时会调用 DAO,那么最好的方法可能就是模拟 DAO正如你所建议的。 在这种情况下,DAO 显然不会被此测试覆盖,但服务会。

如果目的是测试 SQL 语句(并且我假设 DAO 仅包含 SQL 语句+可能将它们转换为域对象),那么模拟不是一个选项。

在这种情况下,测试应该包括对某种数据库的调用,但在这种情况下,它不再被称为单元测试(单元测试是 运行 非常快并且仅在内存,没有 DB,没有 I/O,等等)我将这称为集成测试(正如你所建议的),但不同的人可能对这种测试有不同的名称。

实际上,我们需要两种测试,因为它们测试的是不同的东西

那么,如何测试呢?

首先应该做出决定,应该使用哪个数据库,这里有3种方法:

  1. 运行 使用真实数据库,在用户之间共享,测试假定其已预安装
  2. 运行 内存数据库
  3. 运行测试套件运行s时的数据库docker镜像,之后销毁

虽然关于哪种方法更好的讨论本身非常有趣,但它超出了这个问题 IMO 的范围,每个选择都有其含义。

完成此决定后,您应该决定如何从代码中使用此数据库。

通常 spring 测试使用以下模式:

  1. 测试前开启交易
  2. 运行 测试(更改数据,甚至更改架构 - 如果需要,添加列、表)。做断言
  3. 不管测试结果如何,回滚事务,让数据和测试前一样

因此,如果您对所有测试都采用这种方法,它们将从 "empty" 数据状态开始,这样就不会出现违反约束的情况 这也有效地解决了 "deletion of the record" 问题,因为当事务回滚时数据无论如何都会被删除。

现在关于交易外记录的删除。

一个明显的方法是直接从测试(在 DAO 之外)执行 sql 删除,这样 DAO(生产代码不会被更改)

您可以将 DataSource/JDBCTemplate 直接注入测试(Spring 测试完全支持这一点)并从那里调用所需的 SQL