为什么人们不访问 Rspec 中的数据库?
我经常看到 Rspec 中使用模拟的代码,如下所示:
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
但为什么他们不添加带有 id => 的 Question
? 123在数据库中,通过get
检索它,并销毁它?这是最佳实践吗?如果我不遵守规则,会发生不好的事情吗?
I often see the code which uses mock in Rspec, like this:
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
But why they don't add a Question
with id => 123 in database, retrieve it by get
, and destroy it? Is this a best practice? If I don't follow the rule, will something bad happen?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您编写行为测试(或单元测试)时,您试图仅测试代码的特定部分,而不是整个堆栈。
为了更好地解释这一点,您只是表达和测试“函数 A 应该使用这些参数调用函数 B”,因此您正在测试函数 A 而不是函数 B,您为其提供了模拟。
这很重要,原因有很多:
实际测试整个堆栈的测试称为“端到端测试”或“集成测试”(取决于测试的内容)。这些也很重要,例如,可以使用一套没有模拟数据库的测试来查看给定的应用程序是否可以在与开发过程中使用的数据库不同的数据库中安全运行,并最终修复包含违规 SQL 语句的函数。
When you write a behavioral test (or a unit test), you're trying to test only a specific part of code, and not the entire stack.
To explain this better, you are just expressing and testing that "function A should call function B with these parameters", so you are testing function A and not function B, for which you provide a mock.
This is important for a number of reasons:
A test that actually test the entire stack is called "end to end testing", or "integration testing" (depending on what it tests). These are important as well, for example a suite of tests without mock database can be used to see if a given application can run safely of a different DB than the one used during development, and eventually fix functions that contain offending SQL statements.
其实很多人都这样,包括我。一般来说,由于测试是为了检查行为,因此向某些人插入数据库条目可能会感觉有点不自然。
Question.new 就足够了,因为无论如何它都会通过 Rails 的有效方法,所以很多人倾向于使用它们,也因为它们更快。
但是,事实上,即使您开始使用工厂,有时您也可能会将数据插入到测试环境中。我个人不认为这有什么问题。
总的来说,在某些情况下,如果测试套件非常大,那么不保存数据库条目可能会很有优势。但如果速度不是您最关心的问题,我想说您实际上不必担心测试的外观,只要它构建得很好并且切中要点即可。
顺便说一句,您不需要销毁测试数据,它会在测试结束后自动完成。因此,除非您正在检查实际的删除方法,否则请避免明确执行此操作。
Actually, many people do, including me. Generally speaking, since tests are there to check behavior, it can feel a bit unnatural to insert database entries to some people.
Question.new would be enough because it goes through the valid methods of rails anyway, so many people tend to use them, also because they are faster.
But, indeed, even if you start using factories, there will be times that you will probably inserting data to your testing environment as well. I personally don't see anything wrong with this.
Overall, in some situations were the testing suite is really large, it can be quite an advantage not to save database entries. But if speed is not your top concern, i would say that you would not really have to worry on how the test looks, as long as it is well constructed and to the point.
BTW, you do not need to destroy test data, it's done automatically after the test ends. So, unless you are checking on the actual delete methods, avoid doing that explicitly.