RSpec与Factory_girl - 销毁对象

时间:2014-02-14 17:15:11

标签: ruby-on-rails activerecord rspec factory-bot

我不想测试两个模型之间的关系。 A course has many enrollments, an enrollment has one course.

当课程被销毁时,与其相关的所有注册都将设置为active = false。这适用于真实的物体,我无法让测试工作,因为无论我做什么,课程都不会被破坏。

describe Enrollment do
  it "deactivates enrollment" do
    course = create(:a_course)
    user = create_user
    enrollment = build(:enrollment)
    enrollment.course = course
    enrollment.user = user
    enrollment.save

    # until now everything works as expected

    expect { course.destroy }.to change { enrollment.active }.to be_false

    # the course isn't being destroyed when calling course.destroy

  end
end

我找不到任何关于在factory_girl文档中销毁factory_girl对象的内容,也许我做错了所以我应该使用“真正的”对象?谢谢!

更新 这是发生变化的模型

class Course < ActiveRecord::Base
  attr_accessible ...

  has_many :users, through: :enrollments
  has_many :enrollments

  before_destroy :deactivate_enrollments

  protected

  def deactivate_enrollments
    enrollments = self.enrollments

    enrollments.each do |e|
      e.active = false
      e.save
    end
  end
end

由于我对此不太确定,我用来测试的课程是一个factory_girl对象。它不是这样创建的:Course.create...。 factory_girl对象是否与ActiveRecord对象具有相同的方法?

以下是factory_girl代码:

FactoryGirl.define do
  factory :course, class: Course do
    titel "Course title"
  end
end

更新2 这是failure message

Enrollment
  deactivates enrolment (FAILED - 1)

Failures:

  1) Enrollment deactivates enrollment
     Failure/Error: expect { course.destroy }.to change(enrollment, :active).from(true).to(false)
       active should have been changed to false, but is now true
     # ./spec/models/enrollment_spec.rb:18:in `block (2 levels) in <top (required)>'

更新3

事实证明,课程没有被破坏。 Course.destroy_allcourse.destroy都无效。无论我是否使用factory_girl创建课程和注册。怎么会这样?

2 个答案:

答案 0 :(得分:4)

<强>更新

我注意到你通过重新加载注册来回答你自己的问题但是,即便如此,我认为你应该改变你的rspec语法,使其更具可读性和表现力。最终结果可能是:

expect { 
  course.destroy
  enrollment.reload
}.to change(enrollment, :active).from(true).to(false)

我认为这是记录代码行为的更好方法,因为它读起来几乎像流利的英语;)

答案 1 :(得分:0)

感谢您的帮助!在写完course.destroy之后,我必须写enrollment.reload以便能够看到有关注册的任何变化。

测试可能如下所示:

expect { [course.destroy, enrollment.reload] }.to change { enrollment.active }.to be_false