Reputation: 6263
I have written the service object below.
class LeadGeneration
def initialize contact_id
@lead = Lead.find_or_initialize_by(contact_id: contact_id)
end
def lead
@lead
end
def activate_lead
lead.active!
end
def stale_lead
lead.stale!
end
end
I am a little confused on how exactly to test it. I have written the spec below
require 'spec_helper'
describe LeadGeneration do
let(:contact) { FactoryGirl.create(:contact) }
it "#activate_lead" do
lg = LeadGeneration.new(contact.id)
expect(lg.lead).to receive(:active!)
lg.activate_lead
end
it "#stale_lead" do
lg = LeadGeneration.new(contact.id)
expect(lg.lead).to receive(:stale!)
lg.stale_lead
end
end
This spec works fine, but I would like to do it without exposing the lead that is generated. How exactly do I go about this. I could use
expect(Lead.any_instance).to receive(:active!)
But from my reading this is bad practice. Any thoughts?
Upvotes: 0
Views: 1150
Reputation: 356
Since in this instance all you're testing is that the lead object receives messages, you can stub #lead
to return a mock object that you set expectations on:
it "#activate_lead" do
lead = double('lead')
lg = LeadGeneration.new(contact.id)
# make #lead return our test double whenever it's called
allow(lg).to receive(:lead) { lead }
# our test double should receive the message
expect(lead).to receive(:active!)
lg.activate_lead
end
This means you could move the #lead
method into a private/protected space, since you don't have to call it directly anymore.
Upvotes: 2