RSpec的固定装置

时间:2012-07-27 08:38:39

标签: ruby-on-rails rspec bdd fixtures

我是新手使用RSpec在使用MySQL数据库的Rails应用程序中编写测试。我已经定义了我的灯具,并在我的规格中加载它们如下:

before(:all) do
  fixtures :student
end

这个声明是否在学生表中保存我的灯具中定义的数据,或者只是在测试运行时将数据加载到表中,并在运行所有测试后将其从表中删除?

3 个答案:

答案 0 :(得分:21)

如果你想使用RSpec的灯具,请在describe块中指定你的灯具,而不是在之前的块中:

describe StudentsController do
  fixtures :students

  before do
    # more test setup
  end
end

您的学生装备将被加载到学生表中,然后在每次测试结束时使用数据库事务回滚。

答案 1 :(得分:5)

首先:您无法在fixtures / :all / :context中使用方法:suite hook。不要试图在这些钩子中使用固定装置(如post(:my_post))。

您可以仅在描述/上下文块中准备灯具作为Infuse早先写的。

致电

fixtures :students, :teachers

不要将任何数据加载到DB中!只需准备辅助方法studentsteachers。 当您第一次尝试访问它们时,需要的记录会被懒散地加载。就在

之前
dan=students(:dan) 

这将以delete all from table + insert fixtures方式加载学生和教师。

所以,如果你准备一些学生在之前(:上下文)挂钩,他们现在就会离开!!

在测试套件中只插入一次记录。

在测试套件的末尾不会删除灯具中的记录。它们将被删除并重新插入到下一个测试套件运行中。

示例:

 #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 loade 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

上述测试中的所有期望都将通过

如果再次运行这些测试(在下一个套件中)并且按此顺序运行,那么

 expect(Student.count).to eq 1

将无法满足!将有3名学生(:dan,:paul和全新的@james)。所有这些都将在students(:dan)之前被删除,并且只会:paul和:dan将再次插入。

答案 2 :(得分:1)

before(:all)保存确切的数据,因为它已加载/创建一次。你做你的事,并在测试结束时保持。这就是为什么bui的链接有after(:all)来销毁或使用before(:each); @var.reload!;end从之前的测试中获取最新数据的原因。我可以在嵌套的rspec describe块中看到使用这种方法。