Andy Harvey
Andy Harvey

Reputation: 12653

how to test that service object is initialized with the correct params?

In a Rails app I have a background job that calls a service object

class MyJob < ActiveJob::Base
  def perform( obj_id )
    return unless object = Object.find(obj_id)
    MyServiceObject.new(object).call
  end
end

I can test that the job calls the service object as follows:

describe MyJob, type: :job do
  let(:object) { create :object }
  it 'calls MyServiceObject' do
    expect_any_instance_of(MyServiceObject).to receive(:call)
    MyJob.new.perform(object)
  end
end

But how to test that the job initializes the service object with the correct params?

describe MyJob, type: :job do
  let(:object) { create :object }
  it 'initializes MyServiceObject with object' do
    expect( MyServiceObject.new(object) ).to receive(:call)
    MyJob.new.perform(object)
  end
end

I want to achieve something like above, but this fails with expects 1 but received 0.

What is the correct way to test a class is initialized correctly?

Upvotes: 2

Views: 1002

Answers (2)

mhutter
mhutter

Reputation: 2916

Apparently my fix to Adilbiy's answer was turned down, so here's my updated answer:

describe MyJob, type: :job do
  let(:object) { create :object }
  it 'initializes MyServiceObject with object' do
    so = MyServiceObject.new(object)
    expect(MyServiceObject).to receive(:new).with(object).and_return(so)
    MyJob.new.perform(object)
  end
end

By mocking MyServiceObject.new with expect(MyServiceObject).to receive(:new).with(object), you overwrite the original implementation. However, for MyJob#perform to work, we need MyServiceObject.new to return an object - which you can do with .and_return(...).

Hope this helps!

Upvotes: 2

Adilbiy Kanzitdinov
Adilbiy Kanzitdinov

Reputation: 658

I might suggest following test:

describe MyJob, type: :job do
  let(:object) { create :object }
  it 'initializes MyServiceObject with object' do
    expect( MyServiceObject).to receive(:new).with(object)
    MyJob.new.perform(object)
  end
end

Upvotes: 0

Related Questions