Question

I wan't to test a relationship between two Models. A course has many enrollments, an enrollment has one course.

When a course is being destroyed, all enrolments connected to it are being set to active = false. This works with real objects, I just can't get the test to work because no matter what I do, the course isn't being destroyed.

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

I couldn't find anything about destroying a factory_girl object in the factory_girl docs, maybe I'm doing it all wrong and I should use "real" objects? Thanks!

Update Here is the model where the change happens

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

As I'm not really sure about this, the course I'm using to test with is a factory_girl object. It's not created like this: Course.create.... Does the factory_girl object have the same methods as the ActiveRecord object?

Here is the factory_girl code:

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

Update 2 Here is the 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)>'

Update 3

It turns out, the course isn't being destroyed. Neither Course.destroy_all or course.destroy works. No matter if I create the course and enrollment with factory_girl or not. How can this be?

Was it helpful?

Solution

UPDATE

I noticed that you answered your own question by reloading the enrollment but, even so, I think you should change your rspec syntax to be more readable and expressive. The final result could be:

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

I think that would be a better way to document the behavior of your code, since it reads almost like fluent english ;)

OTHER TIPS

Thanks for the help! It turns out I have to, after writing course.destroy, write enrollment.reload to be able to see any changes concerning the enrollment.

The test could then look like this:

expect { [course.destroy, enrollment.reload] }.to change { enrollment.active }.to be_false
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top