为什么人们不访问 Rspec 中的数据库?

发布于 2024-12-01 03:18:44 字数 423 浏览 0 评论 0原文

我经常看到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深巷少女 2024-12-08 03:18:44

当您编写行为测试(或单元测试)时,您试图仅测试代码的特定部分,而不是整个堆栈。

为了更好地解释这一点,您只是表达和测试“函数 A 应该使用这些参数调用函数 B”,因此您正在测试函数 A 而不是函数 B,您为其提供了模拟。

这很重要,原因有很多:

  1. 您不需要在构建代码的每台机器上安装数据库,如果您开始在公司中使用构建机器(和/或持续集成)来处理数百个项目,这一点很重要。
  2. 您可以获得更好的测试结果,因为如果功能 B 损坏,或者数据库无法正常工作,您不会在功能 A 上出现测试失败
  3. 。您的测试运行得更快。
  4. 在每次测试之前拥有一个干净的数据库总是很痛苦。如果之前运行的测试被停止,在数据库中留下带有该 ID 的问题怎么办?您可能会因为重复的 id 而导致测试失败,而实际上该功能运行正常。
  5. 在运行测试之前,您需要正确的配置。这并不是一个令人难以置信的问题,但如果测试可以“开箱即用”运行,而不需要配置数据库连接、临时测试文件的文件夹、用于测试电子邮件内容的 SMTP 服务器等,那就更好了......

实际测试整个堆栈的测试称为“端到端测试”或“集成测试”(取决于测试的内容)。这些也很重要,例如,可以使用一套没有模拟数据库的测试来查看给定的应用程序是否可以在与开发过程中使用的数据库不同的数据库中安全运行,并最终修复包含违规 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:

  1. You don't need a database installed on every machine you build your code, this is important if you start using build machines (and/or continuous integration) in your company with hundreds of projects.
  2. You get better test results, cause if function B is broken, or the database is not working properly, you don't get a test failure on function A.
  3. Your tests run faster.
  4. It's always a pain to have a clean DB before each test. What if a previous run of your tests was stopped, leaving on the database a Question with that id? You'll probably get a test failure because of duplicate id, while in reality the function is working properly.
  5. You need a proper configuration before running your test. This is not such an incredible problem, but it's much better if tests can run "out of the box", without having to configure a database connection, a folder of temporary test files, an SMTP server for testing email stuff, etc...

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.

不知所踪 2024-12-08 03:18:44

其实很多人都这样,包括我。一般来说,由于测试是为了检查行为,因此向某些人插入数据库条目可能会感觉有点不自然。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文