轨道单元测试是否应该命中数据库?

use*_*ser 3 testing unit-testing ruby-on-rails

我一直在为我的rails应用程序编写测试.我使用TestUnit进行单元测试和功能测试.我也使用黄瓜进行GUI测试.

但是我发现http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database说单元测试最好不要打到数据库.

我同意击中数据库需要相当长的时间.我已经使用spork来减少环境负荷.

在测试rails应用程序时,最佳做法是什么?

Ada*_*gan 21

这是你不应该对名字过于笼罩的情况之一.Rails指的是将ActiveRecord模型作为"单元"测试运行的测试,主要是因为它们是框架直接支持的最低级别测试.根据测试传说,我承认我倾向于相当一致地进行切割,单元测试应该没有测试单元外部的依赖性; 这意味着持久性机制,即数据库.

也就是说,在没有数据库的情况下测试任何复杂的ActiveRecord模型会很快让你想吃掉你的手.Rails假定您使用数据库进行测试; 这就是框架编写的方式.您可以尝试将所有内容存根,但最终会失败,因为您最终会陷入ActiveRecord关联的内部(不适合胆小的人).您可以尝试将所有与非持久性相关的代码提取到不使用数据库进行测试的单独模块中,但是您将创建相当多的不必要的复杂性.

不要试图打击框架.ActiveRecord和ActionController在生产和测试中都有非常特定的预期用途模式.毕竟,Rails就是惯例.如果你遵循使用模式,你将会做更少的工作,并且变得更少受挫,而不是你为了坚持单元测试理想而对抗惯例.如果它让您感觉更好,请将您的ActiveRecord测试视为"模型"测试,并将您的功能测试视为"控制器"测试(这是rspec使用的术语,顺便说一句).

总而言之,您不应在模型测试(或规范)中不必要地访问数据库.某些验证(例如唯一性)需要数据库,但大多数验证都不需要.许多与创建/保存回调和关联相关的操作都需要数据库,但其他操作则不需要.请注意您正在调用的操作正在执行的操作.


Gar*_*eth 5

单元测试不应访问数据库。如果有正确的数据(无论数据来自何处),他们应该测试这些方法是否按预期运行。因此,应根据需要进行打桩/模拟操作,以确保隔离每个单元测试。

但是,集成测试(例如,您可能使用Cucumber编写的)应该将整个MVC堆栈绑定在一起,并且没有理由不使这些命中数据库