使用Rspec和Factory Girl测试before_save回调函数

7

我相信我在这里错过了一些非常基础的东西。

我想测试一个before_save回调是否按照预期进行,而不仅仅是它是否被调用。

我编写了以下测试:

it 'should add lecture to question_type' do      
  @course = Factory :course,
                    :start_time => Time.now - 1.hour,
                    :end_time => Time.now                        
  @question = Factory.create(:question, 
                             :course_id => @course.id, 
                             :created_at => Time.now - 10.minutes)                          
  @question.question_type.should == 'lecture'      
end

我有以下关于 课程问题 的工厂函数:

Factory.define :course do |c|
  c.dept_code {"HIST"}
  c.course_code { Factory.next(:course_code) }
  c.start_time { Time.now - 1.hour }
  c.end_time { Time.now }
  c.lecture_days { ["Monday", Time.now.strftime('%A'), "Friday"]  }
end

Factory.define :question do |q|
  q.content {"Why don't I understand this class!?"}
  q.association :course
end

我在我的Question模型中编写了以下回调函数:

before_save :add_type_to_question

protected

def add_type_to_question
  @course = Course.find(self.course_id)
  now     = Time.now
  if (time_now > lecture_start_time && time_now < lecture_end_time ) && @course.lecture_days.map{|d| d.to_i}.include?(Time.now.wday)
    self.question_type = "lecture"
  end    
end

测试失败并显示“got: nil”,表示问题类型未定义为“lecture”。
由于实现代码没有明显的错误,我在开发环境中尝试了回调函数,它成功地将“lecture”添加到问题类型中。
这使我认为测试可能存在问题。请问我漏掉了什么?Factory.create 默认跳过回调函数吗?

不要使用 before_save,尝试使用 before_validation。 - cpuguy83
1个回答

9

在触发过程时,我不会使用Factory.create。应该使用FactoryGirl创建测试设置,而不是触发要测试的实际代码。你的测试看起来应该像这样:

it 'should add lecture to question_type' do      
  course = Factory(:course, :start_time => Time.now - 1.hour, :end_time => Time.now)
  question = Factory.build(:question, :course_id => course.id, :created_at => Time.now - 10.minutes, :question_type => nil)

  question.save!                          
  question.reload.question_type.should == 'lecture'      
end

如果这个测试仍然失败,您可以开始调试:
add_type_to_question 中添加puts语句,并在 if 语句内再添加一个puts语句,看看会发生什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接