0

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!

3 Answers 3

2

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 
Sign up to request clarification or add additional context in comments.

Comments

0

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 

2 Comments

This is closer to what I am looking for. Is there a way to mock it rather than actually putting it into the database?
Depending on what's your approach on testing. I rather save something in db and test it's "behaviour" then stub something out. Example: if I write a test that checks if it saves it in db then I can exchange api provider without breaking specs. However I have no clue on what are you working and can't tell you what's best for you :)
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.