对旧问题的新答案(但情况有所发展):
如何模拟要测试的数据库(Java)?
您不会模拟它。您嘲笑您的存储库,但不对其进行测试,或者在测试中使用相同的数据库,然后对sql进行测试。所有内存数据库都不完全兼容,因此它们不会为您提供全面的覆盖范围和可靠性。永远不要尝试模拟/模拟连接,结果集等深层db对象。它根本没有任何价值,是开发和维护的噩梦
拥有个人测试数据库几乎是不可能的。您必须使用一个“公共”数据库,每个人都可以使用
不幸的是,许多公司仍然使用该模型,但是现在我们有了docker,几乎每个数据库都有映像。商业产品有一些局限性(例如,高达几GB的数据)对于测试而言并不重要。您还需要在此本地数据库上创建架构和结构
“这些测试肯定不会很快…”-DB测试往往比常规测试慢。进行缓慢的测试真的不理想。
是的,数据库测试速度较慢,但并不是那么慢。我做了一些简单的测量,一个典型的测试用了5-50ms。需要时间的是应用程序启动。有很多方法可以加快速度:
- 第一个DI框架(例如spring)提供了仅运行应用程序某些部分的方式。如果您编写的应用程序将db和与db无关的逻辑很好地分开,那么在您的测试中,您只能启动db部分
- 每个数据库都有大量的调优选项,使其耐用性降低,速度更快。非常适合测试。postgres的例子
您也可以将整个数据库放入tmpfs
另一个有用的策略是设置测试组,并在默认情况下关闭数据库测试(如果它们确实减慢了构建速度)。这样,如果某人实际上正在处理db,则需要在cmd行中传递其他标志或使用IDE(testng组和自定义测试选择器非常适合此操作)
对于每种情况,都应进行一定数量的插入/更新查询,这很烦人并且需要时间
上面讨论了“花时间”部分。讨厌吗 我看过两种方法:
- 为所有测试用例准备一个数据集。那么您必须维护它并对此进行推理。通常它与代码分开。它具有千字节或兆字节。在一个屏幕上看到,理解和推理是很大的。它引入了测试之间的耦合。因为当您需要更多行用于测试A时,您
count(*)
的测试B会失败。它之所以增长是因为即使删除了一些测试,您也不知道该测试仅使用了哪些行 - 每个测试准备其数据。这样,每个测试都是完全独立,可读且易于推理的。讨厌吗 imo,一点也不!它使您可以非常快速地编写新测试,并节省了以后的工作量
您怎么知道该表中有542行?”-测试的主要原则之一就是能够以与测试代码不同的方式测试功能
嗯…不是真的。主要原理是检查您的软件是否响应特定输入生成了所需的输出。因此,如果您拨打
dao.insert542次,然后
dao.count返回542,则表示您的软件按指定方式工作。如果需要,可以在两者之间调用提交/删除缓存。当然,有时您想测试实现而不是合同,然后检查dao是否更改了数据库的状态。但您始终使用sql
B测试sql A(插入vs选择,序列next_val vs返回值等)。是的,您始终会遇到“谁将测试我的测试”的问题,答案是:没有人,因此请保持简单!
其他可能帮助您的工具:
testcontainers将帮助您提供真实的数据库。
dbunit-将帮助您清除测试之间的数据
缺点:
* 创建和维护架构和数据需要大量工作。特别是在您的项目处于密集开发阶段时。* 这是另一个抽象层,因此,如果您突然想使用此工具不支持的某些数据库功能,可能很难对其进行测试
- testegration-旨在为您提供完整的,随时可用的和可扩展的生命周期(公开:我是创作者)。
缺点:
* 仅针对小型项目免费* 非常年轻的项目
- 飞路或liquibase -数据库迁移工具。它们可以帮助您轻松地在本地db上创建架构和所有结构以进行测试。



