模拟PHPUnit中所有单元测试的数据库

时间:2011-06-02 12:23:32

标签: unit-testing mocking phpunit

我刚刚开始研究使用PHPUnit进行单元测试,并且想知道是否有可能为我的所有测试模拟整个数据库。我的模型类(Table Row对象被包装以提供ActiveRecord实现)植根于数据库,一些模型具有许多级别的其他模型类,因此模拟所有这些看起来像是后端的痛苦。

是否有可能让PHPUnit使用CSV文件中的数据作为我的数据库并在那里对数据运行我的测试而不必触摸我的DAO?我已经阅读了PHPUnit中有关数据库测试的部分,但我不确定这是我想要的,因为它不是我想要测试数据库或与数据库交互的代码,更多的是我的模型类是与数据库紧密相关,不得不一直嘲笑事情。如果我可以给它一个CSV文件作为我的数据库,那么我可以将我的数据放入CSV文件并继续正常进行。

我不确定自己是否清楚,请求澄清。如果有可能实现这一点,那就太棒了。如果没有这个单元测试,这种野兽可能不实用,但我真的想将单元测试引入该项目。

由于

齐亚德

4 个答案:

答案 0 :(得分:2)

我认为使用DBUnit测试依赖于数据库的代码有一些好处。我同意,这些可能适用于所有人,也可能不适用。直到最近我才自己使用DBUnit,因为我发现这对我参与的小项目来说太过分了。

使用DBUnit将测试与数据库分离。您测试的系统不应该依赖于DB服务器来运行,您希望尽可能多地隔离。这通常不是什么大问题,因为很多人使用单元测试进行集成测试,为此您更希望使用尽可能匹配生产环境的数据库设置。

DBUnit有利的另一个原因是它在编写测试时节省了时间。 编写测试不是我喜欢的编码的一部分,并且尽可能使用模拟可以节省大量时间。当然,创建数据库的副本很简单,但是您仍然必须制作脚本来加载测试数据,让脚本在每次测试运行之间重置测试数据。许多测试将取决于特定的数据集,并且在添加测试时这会更难维护。当然,所有这些设置都需要与实际应用程序保持同步。根据应用程序的不同,这可能会非常耗时 非常 。有些应用程序有数千个测试,当应用程序中的简单更改导致20个测试及其数据集必须重写时,它会令人心碎。

所有这一切,有一个学习曲线使用DBUnit ,并且第一次使用它时可能会耗费一些时间。一旦进行一次测试,就可以节省后续测试的时间。我不是在任何地方都使用它,因为我编写了许多依赖于实际服务器的测试,但是新代码&我编写的测试我尝试在初始的DBUnit设置上进行构建,并且清楚地表明这确实可以节省中的时间

我2美分的好朋友。

答案 1 :(得分:1)

如何使用数据库但不提交更改?或者在测试运行后回滚?我们将生产站点的副本用作单独服务器上的测试环境,并在那里进行所有测试。

答案 2 :(得分:0)

您可以创建数据库的副本,只需在测试引导中连接到此副本即可?

我有点处于相同的情况,这是我目前正在制定的选项...不完美,但至少它会让第一次测试工作

答案 3 :(得分:0)

之前对我有用的技术是直接模拟数据库适配器并将模拟注入依赖关系链。这仅适用于非常小型单元,因为使模拟适配器返回您希望从特定查询返回的数组结构是一件非常痛苦的事情。如果单个方法调用中涉及多个查询,则根本不起作用。

我获得成功的另一个策略是将dbUnit用于数据库的setUp和tearDown。夹具数据存储在XML或Yaml文件中,并在每次测试之前导入到空数据库中,从而提供已知状态。给定模式和最小数据集,内存数据库将通过避免磁盘I / O问题合理地快速运行测试。

最后,考虑一下你是否需要为数据持久性编写测试...如果你正在测试一个ActiveRecord实现,你可能会有一些测试来证明库级别的基本CRUD操作。您真正对测试感兴趣的内容不依赖于数据库,而是在给定已知起点时内存中对象的行为与预期一致。您可以通过在内存中创建对象 来获得一个已知的起点,而无需将其加载或保存到数据库中。

只需通过创建一些对象来设置内存中的预期状态,运用业务逻辑,查询最终状态,从不打扰调用“保存”......或者无论你怎么称呼它。如果您只需要一个看起来像数据库连接以满足依赖关系的对象,那么您就有了一个模拟...