Ruby-on-rails RSpec 中的夹具
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11684300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fixtures in RSpec
提问by Kris
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:
我刚开始使用 RSpec 在使用 MySQL 数据库的 Rails 应用程序中编写测试。我已经定义了我的装置并将它们加载到我的规范中,如下所示:
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?
此声明是否将我的装置中定义的数据保存在学生表中,还是只是在测试运行时加载表中的数据并在所有测试运行后将其从表中删除?
回答by infused
If you want to use fixtures with RSpec, specify your fixtures in the describe block, not within a before block:
如果你想在 RSpec 中使用设备,请在 describe 块中指定你的设备,而不是在 before 块中:
describe StudentsController do
fixtures :students
before do
# more test setup
end
end
Your student fixtures will get loaded into the students table and then rolled back at the end of each test using database transactions.
您的学生装置将被加载到学生表中,然后在每次测试结束时使用数据库事务回滚。
回答by Foton
First of all: You cannot use method fixturesin :all/ :context/ :suite hook. Do not try to use fixtures in these hooks (like post(:my_post)).
首先:您不能使用方法fixtures在:all/ :context/ :suite hook。不要尝试在这些钩子中使用夹具(如post(:my_post))。
You can prepare fixtures only in describe/context block as Infuse write earlier.
您只能在描述/上下文块中准备夹具,因为 Infuse 之前写入。
Call
称呼
fixtures :students, :teachers
do not load any data into DB! Just prepares helper methods studentsand teachers.
Demanded records are loaded lazily in the moment when You first try to access them. Right before
不要将任何数据加载到数据库中!只需准备辅助方法students和teachers. 请求的记录在您第一次尝试访问它们的那一刻被延迟加载。就在之前
dan=students(:dan)
This will load students and teachers in delete all from table + insert fixturesway.
这将给学生和教师带来负担delete all from table + insert fixtures。
So if you prepare some students in before(:context) hook, they will be gone now!!
所以如果你在 before(:context) 钩子里准备了一些学生,他们现在就会消失!!
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 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
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.
不会遇到!将有 3 名学生(:dan、:paul 和新来的 @james)。所有这些都将被删除students(:dan),只有 :paul 和 :dan 会再次插入。
回答by pjammer
before(:all)keeps the exact data around, as it's loaded/created once. You do your thing, and at the end of the test it stays. That's why bui's link has after(:all)to destroy or use before(:each); @var.reload!;endto get the latest data from the tests before. I can see using this approach in nested rspec describe blocks.
before(:all)保留确切的数据,因为它被加载/创建一次。你做你的事,在测试结束时它会保持不变。这就是为什么 bui 的链接必须after(:all)销毁或使用before(:each); @var.reload!;end之前从测试中获取最新数据的原因。我可以看到在嵌套的 rspec 描述块中使用这种方法。

