【问题标题】:RSpec with Factory_girl - destroy objectRSpec with Factory_girl - 销毁对象
【发布时间】:2014-02-14 17:15:10
【问题描述】:

我不想测试两个模型之间的关系。 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 创建课程和注册。这怎么可能?

【问题讨论】:

  • 这将有助于查看您正在更改相关注册活动状态的模型
  • 我更新了原始问题并添加了模型@Vimsha。
  • 你是否在某处存根破坏方法?
  • 我不知道。我可以测试一下吗?

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


【解决方案1】:

更新

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

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

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

【讨论】:

  • 谢谢,但我得到了同样的失败信息,它仍然是真的。我也尝试写course.destroy,然后写expect(course).to be_nil,但效果不佳。我错误地认为 factory_girl 对象通常可以像这样被销毁吗?
  • 失败信息是什么?
  • 不,这并没有改变任何东西。
  • 天啊。如果您在销毁之前检查课程的注册集合,它会显示有多少项目?
【解决方案2】:

感谢您的帮助!事实证明,我必须在写完course.destroy 之后再写enrollment.reload 才能看到有关注册的任何变化。

测试可能如下所示:

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

【讨论】:

  • 太棒了!但是,我仍然认为我所使用的语法更具可读性,并且在 rspec 文档中被推荐。你能试试expect { [course.destroy, enrollment.reload] }.to change(enrollment, :active).from(true).to(false)吗?然后,我会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多