如何在rspec测试中跳过服务调用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在rspec测试中跳过服务调用相关的知识,希望对你有一定的参考价值。

我正在为这项服务编写测试。

  def run
    sort_offers(product).each do |product_code|
      ......
      offer.update(poduct_params)
      Importer::Partner.get_details(product_code).new
    end
  end

它调用的服务在某些情况下会覆盖运行offer.update(product_prams)时保存的值。我如何在测试中跳过服务电话?

这是我测试的例子

 context 'is valid' do
  .... .....
  before do
    Importer::ProductCodes(product).run
  end
  it ......
end
答案

RSpec有一个非常强大的存根和模拟库(rspec mocks)。

require 'spec_helper'

module Importer
  class Partner
    def self.get_details(product_code)
      "original return value"
    end
  end
end

class FooService
  def self.run
    Importer::Partner.get_details('bar')
  end
end

RSpec.describe FooService do
  let(:partner_double) { class_double("Importer::Partner") }

  before do
    stub_const("Importer::Partner", partner_double)
    allow(partner_double).to receive(:get_details).and_return 'our mocked value'
  end

  it "creates a double for the dependency" do
    expect(FooService.run).to eq 'our mocked value'
  end
end

class_double为类创建了一个double,您可以使用.expect.allow以及模拟界面设置返回值。这是非常有用的,因为你可以删除newintialize方法来返回双重或间谍。

当规范完成时,stub_constant会将常量重置为其先前的值。

这就是说你可以通过在服务中使用构造函数注入来避免使用stub_constant

class PhotoImportService

  attr_accessor :client, :username

  def initialize(username, api_client: nil)
    @username = username
    @client = api_client || APIClient.new(ENV.fetch('API_KEY'))
  end

  def run
    client.get_photos(username)
  end
end
另一答案

我会发送Importer::Partner.get_details来返回响应doublenew

context 'is valid' do
  before do
    allow(Importer::Partner).to receive(:get_details).and_return(double(new: nil))
  end  

  # it ...
end

根据您的需要,您可能希望添加一个期望,即使用正确的参数调用模拟,并且实际上也在模拟上调用了new

context 'is valid' do
  let(:mock) { double(new: nil) }

  before do
    allow(Importer::Partner).to receive(:get_details).and_return(double(new: nil))
  end  

  it "calls the service" do
    an_instance.run

    expect(Importer::Partner).to have_received(:get_details).with(
      foo: 'bar' # the arguments you would expect
    )
    expect(mock).to have_received(:new)
  end
end

以上是关于如何在rspec测试中跳过服务调用的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 中跳过关于 *** DNS 可用性的集成测试

如何在 Maven 安装目标中跳过测试,同时在 Maven 测试目标中运行它们?

如何在 gitlab-ci build 中跳过前面的 maven 目标?

从 IBAction 调用的 dispatchqueue.main.async 中跳过了 Https 请求

在 Maven 中跳过某些模块中的测试

跳过 Factory Girl 和 Rspec 的回调