Reputation: 959
I have a class that puts some info into a database. Here is the method from the class I'm testing:
def load(configs)
opts = { access_token: configs['token'],
api_endpoint: configs['endpoint'],
web_endpoint: configs['site'],
auto_paginate: configs['pagination']}
client = Octokit::Client.new(opts)
repos = client.org_repos(configs['org'])
repos.each do |r|
Project.create(name: r.name)
end
rescue NoMethodError
raise GitConfigError, 'put something here yet'
end
end
I successfuly can test if it raises an error, however I don't know how to go about testing if the data is being put into the database correctly. I can't seem to find any resources on it either. Though, I did test the model in another spec. Any insight would be appreciated!
Upvotes: 0
Views: 956
Reputation: 106882
I would stub both methods - the API call and the save into the database. The API call should be tested in the gem. And create
is tested in Rails. You can assume that both methods work like described in the docs. Edge cases (like failing calls to creates cause of failing validations) should be tested separately.
I would write the spec like this:
context '#load' do
let(:options) { token: 'foo', ... }
let(:repos) { [{ name: 'bar'}] }
let(:client) { instance_double(Octokit::Client, repos) }
before do
allow(Octokit::Client).to_receive(:new).and_return(client)
allow(Project).to_return(:create).and_return(true)
end
it 'initializes the API client' do
thing.load(options)
expect(Octokit::Client).to have_received(:new).with(
access_token: options[:token],
# ...
)
end
it 'stores records received from the API' do
thing.load(options)
expect(Project).to have_received(:create).with(name: 'baz')
end
end
Upvotes: 2
Reputation: 2786
In my opinion you can go with
expect_any_instance_of(Octokit::Client).to receive(:org_repos).and_return([{name: "a"}, {name: "b"}])
You can find more information on rspec documentation
Upvotes: 0
Reputation: 606
I'm not sure if I understand you correctly but if by 'if the data is being processed correctly' you mean if it got saved in the database you could do something like
it "saves Project in db" do
expect { subject.load([{name: "a"}, {name: "b"}]) }.to change(Project.count).from(0).to(2)
end
it "saves it with correct data" do
subject.load([{name: "a"}, {name: "b"}])
expect(Project.all.map(&:name)).to eql ["a", "b"]
end
or if the Octokit::Client.new(opts)
is an external api you could use something like webmock or vcr to stub out api calls
it "calls external api and creates Project based on this data" do
stub_request(:get, "http://api.example.com/cats").and_return([{name: "a"}, {name: "b" }])
subject.load()
expect(Project.all.map(&:name)).to eql ["a", "b"]
end
Upvotes: 0