Kyl*_*Fox 5 testing ruby-on-rails shoulda factory-bot
我正在寻找一种方法来加速我的Shoulda + FactoryGirl测试.
我试图测试的模型(StudentExam
)与其他模型有关联.在创建之前,这些关联对象必须存在StudentExam
.出于这个原因,它们是在中创建的setup
.
但是,我们的一个模型(School
)需要很长时间才能创建.因为setup
每一个之前被调用should
语句时,整个测试用例需要亿万年来执行-它创建了一个新的@school
,@student
,@topic
和@exam
每一个应声明执行.
我正在寻找一种只创建一次这些对象的方法.是否有类似startup
for before_all
方法的东西可以让我创建记录,这些记录会在测试用例的其余部分持续存在?
基本上我之前正在寻找与RSpec 之前完全相同的东西(:全部).我不关心依赖的问题,因为这些测试永远不会修改那些昂贵的对象.
这是一个示例测试用例.为长代码道歉(我也创造了一个要点):
# A StudentExam represents an Exam taken by a Student.
# It records the start/stop time, room number, etc.
class StudentExamTest < ActiveSupport::TestCase
should_belong_to :student
should_belong_to :exam
setup do
# These objects need to be created before we can create a StudentExam. Tests will NOT modify these objects.
# @school is a very time-expensive model to create (associations, external API calls, etc).
# We need a way to create the @school *ONCE* -- there's no need to recreate it for every single test.
@school = Factory(:school)
@student = Factory(:student, :school => @school)
@topic = Factory(:topic, :school => @school)
@exam = Factory(:exam, :topic => @topic)
end
context "A StudentExam" do
setup do
@student_exam = Factory(:student_exam, :exam => @exam, :student => @student, :room_number => "WB 302")
end
should "take place at 'Some School'" do
assert_equal @student_exam, 'Some School'
end
should "be in_progress? when created" do
assert @student_exam.in_progress?
end
should "not be in_progress? when finish! is called" do
@student_exam.finish!
assert !@student_exam.in_progress
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果问题是仅创建这些记录一次,则可以使用类变量。这不是一个干净的方法,但至少应该有效。
# A StudentExam represents an Exam taken by a Student.
# It records the start/stop time, room number, etc.
class StudentExamTest < ActiveSupport::TestCase
should_belong_to :student
should_belong_to :exam
# These objects need to be created before we can create a StudentExam. Tests will NOT modify these objects.
# @school is a very time-expensive model to create (associations, external API calls, etc).
# We need a way to create the @school *ONCE* -- there's no need to recreate it for every single test.
@@school = Factory(:school)
@@student = Factory(:student, :school => @@school)
@@topic = Factory(:topic, :school => @@school)
@@exam = Factory(:exam, :topic => @@topic)
context "A StudentExam" do
setup do
@student_exam = Factory(:student_exam, :exam => @@exam, :student => @@student, :room_number => "WB 302")
end
should "take place at 'Some School'" do
assert_equal @student_exam, 'Some School'
end
should "be in_progress? when created" do
assert @student_exam.in_progress?
end
should "not be in_progress? when finish! is called" do
@@student_exam.finish!
assert !@student_exam.in_progress
end
end
end
Run Code Online (Sandbox Code Playgroud)
编辑:要修复超级丑陋的解决方法,请使用实例方法推迟评估。
# A StudentExam represents an Exam taken by a Student.
# It records the start/stop time, room number, etc.
class StudentExamTest < ActiveSupport::TestCase
...
private
def school
@@school ||= Factory(:school)
end
# use school instead of @@school
def student
@@school ||= Factory(:student, :school => school)
end
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1130 次 |
最近记录: |