我正在使用 HSQLDB 进行单元测试。有没有一种很好的方法来模拟各种数据库问题,如约束违规、ORM 层异常或彻底的数据库中断,同时使用 HSQLDB 而不显式模拟 ORM 层?
2 回答
看起来这很难做到,因为内存数据库并没有真正变得断开连接或类似。不过,您的情况有几个选择:
要伪造违反约束,请执行一些破坏约束的操作。例如,对于唯一约束,预先添加一个重复行,对于外键约束,当被测系统不期望它时删除引用的外行,等等。
ORM 层异常很棘手。对数据库做一些疯狂的事情可能是在这里得到一些反应的最简单的方法(例如删除所有表),但我认为你将很难重现许多可能的问题。
使用内存数据库并不能真正直接伪造数据库中断,因为它确实总是可以访问的。解决方案是进入被测系统和数据库之间的层,并断开那里的连接,这是可能的。我目前正在使用 Spring 和 JDBC 模板在 Java 项目上执行此操作,并且我正在分别模拟 DB 超时和中断:
DriverManagerDataSource dataSource =
((DriverManagerDataSource)jdbcTemplate.getDataSource());
// 192.0.2.1 is in the TEST-NET range, guaranteed
// to never exist, so this always times out
dataSource.setUrl("jdbc:hsqldb:http://192.0.2.1/testdb");
// Subsequent operations then timeout
和
// Port 9 is reserved for 'discard', so is almost certainly unconnectable
// and very very unlikely to ever actually return valid data even if not.
dataSource.setUrl("jdbc:hsqldb:http://localhost:9/testdb");
// Subsequent operations immediately fail to connect
请注意,这两个都会中断新的连接,据我所知,没有办法中断所有当前打开的连接。如果你能得到一个参考,close()ing 它应该非常接近模拟飞行中的断开连接。
此外,正如布塔所指出的,这是一个集成测试,而不是单元测试。除了进行这些集成测试之外,您可能还希望在此处对与数据库通信的代码进行单元测试,并为此完全模拟您的数据库接口(例如,您的 JDBC 模板)。这实际上使很多事情变得更容易,尤其是模拟特定的异常场景。
对于中断,您可以尝试不启动数据库。对于所有其他事情,我更喜欢模拟 ORM 层。
顺便说一句:当使用 HSQLDB 时,它实际上不再是单元测试了。它更像是一个集成测试。