RSpec 中的夹具
Posted
技术标签:
【中文标题】RSpec 中的夹具【英文标题】:Fixtures in RSpec 【发布时间】:2012-07-25 22:12:18 【问题描述】:我是使用 RSpec 在使用 mysql 数据库的 Rails 应用程序中编写测试的新手。我已经定义了我的固定装置,并将它们加载到我的规范中,如下所示:
before(:all) do
fixtures :student
end
此声明是将我的夹具中定义的数据保存在学生表中,还是只是在测试运行时加载表中的数据并在所有测试运行后将其从表中删除?
【问题讨论】:
试试factory_girl或fabrication,而不是fixtures。 【参考方案1】:如果您想在 RSpec 中使用fixture,请在 describe 块中指定您的 fixture,而不是在 before 块中:
describe StudentsController do
fixtures :students
before do
# more test setup
end
end
您的学生设备将被加载到学生表中,然后在每次测试结束时使用数据库事务回滚。
【讨论】:
relishapp.com/rspec/rspec-rails/docs/model-specs/…【参考方案2】:首先:你不能在:all
/:context
/:suite hook
中使用方法fixtures
。不要尝试在这些钩子中使用固定装置(例如 post(:my_post)
)。
您只能在描述/上下文块中准备固定装置,就像 Infuse 之前写的那样。
打电话
fixtures :students, :teachers
不要将任何数据加载到数据库中!只需准备辅助方法students
和teachers
。
当您第一次尝试访问所需的记录时,它们会延迟加载。之前
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。
【讨论】:
是的!我找到了在所有测试之前加载所有固定装置的技巧。只需添加 RSpec.configure |config| config.global_fixtures= :all AND 直接在 spec_helper 中测试,它将尝试访问任何夹具。这样所有的灯具都会提前加载。【参考方案3】:before(:all)
保留确切的数据,因为它被加载/创建一次。你做你的事,在测试结束时它会留下来。这就是为什么bui的链接有after(:all)
来销毁或使用before(:each); @var.reload!;end
从之前的测试中获取最新数据的原因。我可以看到在嵌套的 rspec 描述块中使用这种方法。
【讨论】:
以上是关于RSpec 中的夹具的主要内容,如果未能解决你的问题,请参考以下文章