Reputation: 2512
I'm new to using rspec, so hopefully I'm explaining this correctly. I want to make sure my object is created and afterwards make sure that a related object with a has_one
relationship is created.
So, my code would look like this in the model:
class Device < ActiveRecord::Base
has_one :scan_option
validates_presence_of :name
after_create :create_scan_option
def create_scan_option
self.scan_option.create!
end
end
I have a Factory for a device:
FactoryGirl.define do
serial_number = SecureRandom.uuid.delete("-")
factory :device do
identifier serial_number
name "Device 1"
is_registered true
timezone "America/Chicago"
end
end
In my rspec model test I imagine the code would look like this:
RSpec.describe Device, :type => :model do
it "creates a scan_option after_create" do
subject = build(:device)
# test whether the scan_option object was created and associated with the device?
end
end
I'm not using shoulda
or anything, just trying to understand Rspec better.
Upvotes: 0
Views: 2072
Reputation: 107132
I would do something like this:
subject(:device) { Device.create(attributes_for(:device)) }
it 'has a scan option' do
expect(device.scan_option).to be_present
end
I would use Device.create
instead of FactoryGirl.create
to ensure that the class itself creates the associated object and that it is not created by the factory.
Upvotes: 2
Reputation: 9028
Several Ways:
subject = build(:device)
expect(subject.scan_option).not_to be_nil
expect { build(:device) }.to change(ScanOption, :count).by(1)
It probably won't pass because you only built your factory.
In order for the callback to be executed you actually have to persist it in the database:
subject = create(:device)
Upvotes: 0
Reputation: 10416
You should just be able to save the device and then call the association and check it returns something
it "creates a scan_option after_create" do
subject = build(:device)
subject.save
expect(subject.scan_option).to be
end
Upvotes: 0