Rspec可以用于类的存根方法

时间:2015-03-17 19:41:12

标签: ruby rspec

我有一个将一些信息放入数据库的类。这是我正在测试的类的方法:

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

我成功地可以测试它是否会引发错误,但是我不知道如何正确地测试数据是否正确地放入数据库中。我似乎无法找到任何资源。虽然,我确实在另一个规范中测试了该模型。任何见解都将不胜感激!

3 个答案:

答案 0 :(得分:2)

我会将两种方法 - API调用和保存到数据库中。应该在gem中测试API调用。并且create在Rails中进行了测试。您可以假设这两种方法的工作方式与文档中描述的相同。边缘情况(如失败的调用会导致验证失败)应单独测试。

我会像这样编写规范:

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  

答案 1 :(得分:0)

我不确定我是否理解正确,但是如果数据处理正确的话,那就是'你的意思是如果它保存在数据库中你可以做类似的事情

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

或者如果Octokit::Client.new(opts)是外部api,你可以使用像webmock或vcr这样的东西来存根api调用

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 :(得分:0)

在我看来,你可以选择 expect_any_instance_of(Octokit::Client).to receive(:org_repos).and_return([{name: "a"}, {name: "b"}])您可以在rspec documentation

上找到更多信息