Why don't people access the database in rspec?

I often see code that uses mock in Rspec, for example:

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 don't they add Question with id => 123 to the database, extract its get and destroy it? Is this the best practice? If I do not follow this rule, will something bad happen?

+4
source share
2 answers

When you write a behavioral test (or unit test), you are trying to test only a specific part of the code, not the entire stack.

To explain this better, you simply express and verify that "function A should call function B with these parameters," so you are testing function A, not function B, for which you provide a layout.

This is important for a number of reasons:

  • You do not need a database installed on each computer on which you create the code, this is important if you start using assembly machines (and / or continuous integration) in your company with the help of hundreds of projects.
  • You get the best test results, causing a violation of function B, or the database does not work properly, you do not receive a test failure in function A.
  • Your tests are faster.
  • It is always painful to have a clean database before each test. What should I do if the previous launch of your tests was stopped, leaving a Question with this identifier in the database? You will likely receive a test failure due to duplicate identifier, while in reality the function works correctly.
  • Before running the test, you need the correct setup. This is not such an incredible problem, but it is much better if the tests can be run out of the box, without the need to configure a database connection, a folder of temporary test files, an SMTP server for testing email materials, etc.

A test that actually checks the entire stack is called "end-to-end testing" or "integration testing" (depending on what it is testing). They are also important, for example, a test suite without a mock database can be used to check whether a particular application can safely work with a different database than that used during development, and ultimately fix functions that contain offensive SQL statements .

+7
source

Actually, many people, including me. Generally speaking, since tests verify behavior, for some users it may seem a little unnatural to insert records into the database.

Question.new will suffice, because it goes through valid rail methods anyway, so many people tend to use them, also because they are faster.

But even if you start using factories, there will be times when you are likely to enter data into your test environment. I personally do not see anything wrong with that.

In general, in some situations, the test suite is really large, it can be quite profitable so as not to store records in the database. But if speed is not your main concern, I would say that you really do not have to worry about how the test looks if it is well designed and appropriate.

By the way, you do not need to destroy the test data, they are executed automatically after the test is completed. So, if you are not checking the actual removal methods, do not do this explicitly.

+2
source

All Articles