Reputation: 4783
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?
Upvotes: 4
Views: 3903
Reputation: 1483
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 ;)
Upvotes: 4
Reputation: 4783
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
Upvotes: 0