Fixtures in RSpec

Viewed 39701

I'm new to using RSpec for writing tests in a Rails application which uses a MySQL database. I have defined my fixtures and am loading them in my spec as follows:

before(:all) do
  fixtures :student
end

Does this declaration save the data defined in my fixtures in the students table or does it just load the data in the table while the tests are running and remove it from the table after all the tests are run?

3 Answers

First of all: You cannot use method fixtures in :all / :context / :suite hook. Do not try to use fixtures in these hooks (like post(:my_post)).

You can prepare fixtures only in describe/context block as Infuse write earlier.

Call

fixtures :students, :teachers

do not load any data into DB! Just prepares helper methods students and teachers. Demanded records are loaded lazily in the moment when You first try to access them. Right before

dan=students(:dan) 

This will load students and teachers in delete all from table + insert fixtures way.

So if you prepare some students in before(:context) hook, they will be gone now!!

Insert of records is done just once in test suite.

Records from fixtures are not deleted at the end of test suite. They are deleted and re-inserted on next test suite run.

example:

 #students.yml
   dan:
     name: Dan 
   paul:
     name: Paul

 #teachers.yml
    snape:
      name: Severus




describe Student do
  fixtures :students, :teachers
  
  before(:context) do
    @james=Student.create!(name: "James")
  end

  it "have name" do
   expect(Student.find(@james.id)).to be_present
   expect(Student.count).to eq 1
   expect(Teacher.count).to eq 0
  
   students(:dan)
   
   expect(Student.find_by_name(@james.name)).to be_blank
   expect(Student.count).to eq 2
   expect(Teacher.count).to eq 1
   
  end
end


#but when fixtures are in DB (after first call), all works as expected (by me)

describe Teacher do
  fixtures :teachers # was loaded in previous tests
  
  before(:context) do
    @james=Student.create!(name: "James")
    @thomas=Teacher.create!(name: "Thomas")
  end

  it "have name" do
   expect(Teacher.find(@thomas.id)).to be_present
   expect(Student.count).to eq 3 # :dan, :paul, @james
   expect(Teacher.count).to eq 2 # :snape, @thomas
  
   students(:dan)
      
   expect(Teacher.find_by_name(@thomas.name)).to be_present
   expect(Student.count).to eq 3
   expect(Teacher.count).to eq 2
   
  end
end

All expectations in tests above will pass

If these test are run again (in next suite) and in this order, than expectation

 expect(Student.count).to eq 1

will be NOT met! There will be 3 students (:dan, :paul and fresh new @james). All of them will be deleted before students(:dan) and only :paul and :dan will be inserted again.

Related