ruby-on-rails - 如何在测试环境中干净地 stub REST 客户端

标签 ruby-on-rails unit-testing testing rspec

我有一个像下面这样的基本模型

class MyModel
    def initialize(attrs)   
        @attrs = attrs
        @rest_client = Some::REST::Client.new 
    end

    def do_a_rest_call(some_str)
      @rest_client.create_thing(some_str)
    end
end

出于测试目的,我不希望@rest_client 进行远程调用。相反,在测试环境中,我只想确保 @rest_client 在经过某些代码分支时被调用到特定的 some_str

在理想世界中,我会有一个类似于以下的断言:

expect(my_model_instance).to.receive(do_a_rest_call).with(some_str) 在测试中我将传递 some_str 以确保它是正确的。

使用 RSpec 3.8 和 Rails 5.2.2 执行此操作的最佳方法是什么?

最佳答案

无需任何额外 gem 即可工作的解决方案:

let(:rest_client_double) { instance_double(Some::REST::Client, create_thing: response) }

it 'sends get request to the RestClient' do
  allow(Some::REST::Client).to receive(:new).and_return(rest_client_double)

  MyModel.new(attrs).do_a_rest_call(some_str)

  expect(rest_client_duble).to have_received(:create_thing).with(some_str).once
end

基本上,您正在为 REST 客户端创建一个替身。 然后,您确保在调用 Some::REST::Client.new 时将使用 double(而不是真正的 REST 客户端实例)。

最后,您在您的模型上调用一个方法并检查是否双重收到了给定的消息。

关于ruby-on-rails - 如何在测试环境中干净地 stub REST 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55123380/

相关文章:

ruby-on-rails - 如何更改脚手架的名称而不重新创建它?

jquery - 如何在 HTML 单元中获取 Ajax 响应(它呈现网页的 HTML)

ruby-on-rails - 使用设计和 cucumber 测试登录

ruby-on-rails - 如何使用 ActionController::Live 以及 Resque + Redis(用于聊天应用程序)

android - PowerMockito spy : Calling real method results with CannotStubVoidMethodWithReturnValue

c++ - catch单元测试框架支持junit风格的测试报告吗?

c# - 断言没有方法被调用

testing - 敏捷测试计划/测试用例,IEEE 829 的轻量级替代品?

测试桌面应用程序

ruby-on-rails - 在 Ruby/Rails 中使用全局变量或常量变量?