我经常看到Rspec中使用mock的代码,如下所示:
describe "GET show" do
it "should find and assign @question" do
question = Question.new
Question.should_receive(:find).with("123").and_return(question)
get :show, :id => 123
assigns[:question].should == question
end
end
但为什么他们不添加一个Question
数据库中 id => 123,通过以下方式检索它get
,并摧毁它?这是最佳实践吗?如果我不遵守规则,会发生不好的事情吗?
当您编写行为测试(或单元测试)时,您试图仅测试代码的特定部分,而不是整个堆栈。
为了更好地解释这一点,您只是表达和测试“函数 A 应该使用这些参数调用函数 B”,因此您正在测试函数 A 而不是函数 B,您为其提供了模拟。
这很重要,原因有很多:
- 您不需要在构建代码的每台机器上安装数据库,如果您开始在公司中使用具有数百个项目的构建机器(和/或持续集成),这一点很重要。
- 您可以获得更好的测试结果,因为如果功能 B 损坏,或者数据库无法正常工作,您不会在功能 A 上获得测试失败。
- 您的测试运行得更快。
- 在每次测试之前拥有一个干净的数据库总是很痛苦。如果之前运行的测试被停止,在数据库中留下带有该 ID 的问题怎么办?您可能会因为重复的 id 而导致测试失败,而实际上该功能运行正常。
- 在运行测试之前,您需要进行正确的配置。这并不是一个令人难以置信的问题,但如果测试可以“开箱即用”运行,而不需要配置数据库连接、临时测试文件的文件夹、用于测试电子邮件内容的 SMTP 服务器等,那就更好了...
实际测试整个堆栈的测试称为“端到端测试”或“集成测试”(取决于测试的内容)。这些也很重要,例如,可以使用一套没有模拟数据库的测试来查看给定的应用程序是否可以在与开发过程中使用的数据库不同的数据库中安全运行,并最终修复包含违规 SQL 语句的函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)