I wanted to test a delayed job that in its performs function calls and external API with some data and if successful updates a record in the database.
class IncomeUploadJob < Struct.new(:person)
def perform
success, result = PersonService.upload_finances(person.income)
if success
rich = RichPeople.new(:name => person.name,
:income => person.income,
:richness_level => result["richness_level"])
rich.save!
end
else
Rails.logger.warn("Upload income job failed")
end
end
end
I wanted to write a simple test for this where I can just call that method and in the end, after the job is completed I could test the Db for the new record. Some guidance will be greatly appreciated.
CodePudding user response:
Example Rspec test
require 'rails_helper'
describe IncomeUploadJob do
describe '#perform' do
let(:person) { create(:person) }
before { stub_api_call }
context 'when success' do
it 'creates RichPeople record' do
IncomeUploadJob.new.perform
RichPeople.reload
expect(RichPeople.count).not_to eq(0)
end
end
def stub_api_call
stub_request(:post, 'https://apiurl.com/access_token').to_return(
body: fixture('access_token.json'),
headers: { 'Content-Type' => 'application/json' }
)
end
end
end
Explanation:
let(:person) { create(:person) }
this may not require in your case, if required, you can createperson
factory and create person record- You can mock/stub your API calls as I did in
stub_api_call
method, createfixure
file if API response is big otherwise you can directly add it here instead of fixure. You can stub more than one API as per your requirement, I just did one. IncomeUploadJob.new.perform
calls the job.
Thanks, let me know if you have any other queries in it
CodePudding user response:
You can use a mock on your service with something like:
describe IncomeUploadJob do
context 'with successful API request' do
subject { described_class.perform_now(person) }
let(:person) { create(:person) } # assume you're using Faker
let(:double_finance_upload) { [true, {"richness_level" => 42} ]}
before do
expect(PersonService).to receive(:upload_finances).with(person.income).and_return(double_finance_upload)
end
it 'creates a new rich person' do
expect{subject}.to change{RichPeople.count}.by(1)
end
end
end