如何在Rails服务中存根依赖项

时间:2015-06-05 20:28:41

标签: ruby-on-rails rspec vcr

我有:

  • 调用第三方API(lib)的Web服务包装器
  • 一个调用该包装器并执行一些finagling(service)的服务

使用VCR测试lib类效果很好,但我不确定如何测试服务。具体来说,我如何在服务中存根API调用?

class GetBazsForBars
  def self.call(token)
    bazs = Foo.new(token).bars

    # do some other stuff
    bazs
  end
end

测试:

require 'rails_helper'

RSpec.describe GetBazsForBars, type: :service do
  describe ".call" do
    let(:token) { Rails.configuration.x.test_token }
    let(:bazs)  { GetBazsForBars.call(token) }

    it { expect(bazs.any?).to eq(true) }
  end
end

我不想将Foo传递给服务。

在Payola中,作者使用StripeMock来模拟响应。我可以写一些类似的东西,比如调用VCR并让服务使用它的FooMock吗?

不确定如何使用Ruby,我习惯于将C#/ Java DI传递给构造函数。

感谢您的帮助。

更新

转到完整答案

2 个答案:

答案 0 :(得分:1)

foo = double(bars: 'whatever')
allow(Foo).to receive(:new).with(:a_token).and_return foo

allow(Foo).to receive(:new).with(:a_token)
  .and_return double(bar: 'whatever')

答案 1 :(得分:0)

@mori提供了一个很好的起点,我最终......

1)存根服务名称的const:

Foo.new

2)在/ spec / fakes中创建一个假foo包装器:

// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(inputFile);

// Always wrap FileReader in BufferedReader.
input = new BufferedReader(fileReader);

total = input.readLine() + "\n";

while ((line = input.readLine()) != null && total != null) {
    total += line + "\n";

    System.out.println("Proof that the file says: " + line);
}

input.close();

这意味着在我的服务中我只能private static String readFile(String inputFile) throws IOException { BufferedReader input; String total; String line;// FileReader reads text files in the default encoding. FileReader fileReader = new FileReader(inputFile); // Always wrap FileReader in BufferedReader. input = new BufferedReader(fileReader); total = input.readLine() + "\n"; while ((line = input.readLine()) != null) { total += line + "\n"; System.out.println("Proof that the file says: " + line); } input.close(); return total; } 并且它处理测试和现实生活(伟大的集成测试)。而且我没有在测试中设置任何模拟链,这需要一个实际的实例来使VCR调用正确。

可能有一种更简单的方法,但代码看起来非常好,所以发货。