Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't people access database in Rspec?

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?

like image 990
Lai Yu-Hsuan Avatar asked Jan 19 '23 21:01

Lai Yu-Hsuan


1 Answers

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.

like image 105
Simone Gianni Avatar answered Jan 21 '23 12:01

Simone Gianni