【问题标题】:unable to mock httparty request on service module test无法在服务模块测试中模拟 httparty 请求
【发布时间】:2016-06-02 20:01:31
【问题描述】:

我正在尝试在我的 HotelsApiService 模块上测试方法“get_all_hotels”:

BASE_URI = ENV['HOTELS_API_URI']

def get_all_hotels
    begin
        RequestService.new(BASE_URI).get("/hotels")
    rescue
        "Unable to get service response"
    end
end

但不能使测试通过这一点。显然问题是当我想模拟 RequestService 的调用时(RequestService 是一个使用 HTTParty 执行 http 请求的类)。

这是测试文件:

require "rails_helper"

describe HotelsApiService do
  let(:base_uri) { "base_uri" }
  let(:request_service) { double }

  subject { Object.new.extend HotelsApiService }

  before do
    allow(ENV).to receive(:[]).with('HOTELS_API_URI') { base_uri }        
  end

  describe "#get_all_hotels" do
    let(:api_response) {
      { hotel: { id: 1, name: "Hotel name", address: "Str 34", star_rating: 3, accomodation_type: "hotel" }}
}

    before do
      allow(RequestService).to receive(:new).with(base_uri) { request_service }
      allow(request_service).to receive(:get).with("/hotels") { api_response }
    end

    it 'responds with hotel' do
      expect(subject.get_all_hotels).to eq(api_response.to_json)
    end

  end
end

这样测试返回以下错误:

Failure/Error: expect(subject.get_all_hotels).to be_a_kind_of(Hotel)
   #<RequestService (class)> received :new with unexpected arguments
     expected: ("base_uri")
          got: (nil)
   Diff:
   @@ -1,2 +1,2 @@
   -["base_uri"]
   +[nil]

    Please stub a default value first if message might be received with other args as well.

如果我尝试以其他方式模拟它:

before do
  allow(RequestService).to receive_message_chain(:new, :edit).with(base_uri, "/hotels") { request_service }
end

我收到另一个错误:

Failure/Error: expect(subject.get_all_hotels).to eq(api_response.to_json)
   #<Double (anonymous)> received unexpected message :get with ("/hotels")

提前致谢

【问题讨论】:

    标签: ruby-on-rails-4 rspec capybara httparty


    【解决方案1】:

    BASE_URI 是在您的源文件加载时设置的,这是在您模拟 ENV 以返回您期望的值之前。因此它等于 nil 并导致您的问题。

    【讨论】:

    • 谢谢@Tom Walpole,我明白你的意思。但是我应该在哪里嘲笑它呢?
    • @ntonnelier 它的编写方式你不能模拟它 - 为了能够模拟它,你需要在运行时评估它,比如 RequestService.new(ENV['HOTELS_API_URI']).get("/hotels") 或者如果你不想访问每次您可以将 ENV 查找移动到类方法中,以便仅在首次使用时对其进行评估 - 然后您可以在您的测试中将其 nil 用于更改它的值。
    猜你喜欢
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多