Railsアプリケーションでテストを作成するためにRSpecを使用するのは初めてです。フィクスチャを定義し、スペックに次のようにロードしています。
before(:all) do
fixtures :student
end
この宣言は、フィクスチャで定義されたデータをstudentテーブルに保存しますか、それとも、テストの実行中にデータをテーブルにロードし、すべてのテストの実行後にテーブルから削除しますか?
RSpecでフィクスチャを使用する場合は、beforeブロック内ではなく、describeブロックでフィクスチャを指定します。
describe StudentsController do
fixtures :students
before do
# more test setup
end
end
学生のフィクスチャは、studentsテーブルに読み込まれ、データベーストランザクションを使用して各テストの最後にロールバックされます。
まず、_:all
_/_:context
_/_:suite hook
_ではメソッドfixtures
を使用できません。これらのフックでフィクスチャを使用しないでください(post(:my_post)
など)。
Infuseが先に書いたように、記述/コンテキストブロックでのみフィクスチャを準備できます。
コール
_fixtures :students, :teachers
_
dBにデータをロードしないでください。ヘルパーメソッド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 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のみが再度挿入されます。
before(:all)
は、一度ロード/作成されると、正確なデータを保持します。あなたはあなたのことをし、テストの終わりにそれは残ります。そのため、buiのリンクにはafter(:all)
を使用して破棄するか、before(:each); @var.reload!;end
を使用して以前のテストから最新のデータを取得します。ネストされたrspec記述ブロックでこのアプローチを使用しているのがわかります。