35

我是使用 RSpec 在使用 MySQL 数据库的 Rails 应用程序中编写测试的新手。我已经定义了我的固定装置并将它们加载到我的规范中,如下所示:

before(:all) do
  fixtures :student
end

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

4

3 回答 3

30

如果您想在 RSpec 中使用夹具,请在 describe 块中指定您的夹具,而不是在 before 块中:

describe StudentsController do
  fixtures :students

  before do
    # more test setup
  end
end

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

于 2014-07-11T05:14:16.640 回答
9

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

正如 Infuse 之前写的那样,您只能在描述/上下文块中准备固定装置。

称呼

fixtures :students, :teachers

不要将任何数据加载到数据库中!只需准备辅助方法studentsteachers. 当您第一次尝试访问所需的记录时,它们会延迟加载。就在之前

dan=students(:dan) 

这会给学生和老师带来负担delete all from table + insert fixtures

所以如果你在 before(:context) 钩子里准备了一些学生,他们现在就消失了!!

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

测试套件结束时不会删除来自夹具的记录。它们在下一次测试套件运行时被删除并重新插入。

例子:

 #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

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

如果这些测试再次运行(在下一个套件中)并按此顺序运行,则超出预期

 expect(Student.count).to eq 1

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

于 2016-09-29T13:28:50.257 回答
1

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

于 2012-12-22T12:10:44.970 回答