我构建了一个向Discorde API发送请求的客户端类.我模拟这个客户端,如下面的示例代码所示.请参考方法#mock_Client:

require 'rails_helper'
require 'discord_client'

RSpec.describe some_service_class do
  describe '#call' do
    let(:client) { mock_client }

    it 'does this using discord_client' do
      client
      
      described_class.new.call
      
      expect(client).to have_received(:new).once
      expect(client).to have_received(:get_guild).once
    end
  end

  private

  def mock_client
    client = instance_double(DiscordClient)

    allow(DiscordClient).to receive(:new).and_return(client)
    allow(client).to receive(:get_guild)
    allow(client).to receive(:get_user)

    client
  end
end

然而,由于我在许多服务和rake任务中使用该客户端,我不想总是在我编写的每个规范文件中都对其进行嘲弄和删减.我可以将我的方法#MOCK_CLIENT移到哪里,这样我就可以在任何规范文件中调用它?提前谢谢!

推荐答案

在RSpec中,您可以使用shared contexts来共享您的测试依赖项(let、let!)或测试设置.这基本上是在其包含的示例组的上下文中进行判断的块:

RSpec.shared_context "Discord mocks" do
  let(:client) { instance_double(DiscordClient) }

  before do
    allow(DiscordClient).to receive(:new).and_return(client)
    allow(client).to receive(:get_guild)
    allow(client).to receive(:get_user) 
  end
end

这些可以手动包含在带有include_context的单独等级库中,也可以通过您的等级库设置来包含.共享上下文通常放置在/spec/support中的某个位置.

另外,首先可以通过提供工厂方法来减少存根的需要,如果不需要单独的初始化和"调用"参数,则应该使用这些方法而不是new.get_guild:

class DiscordClient
  def self.get_guild(...)
    new.get_guild(...)
  end
end

然后,您需要做的就是存根您的客户端公开的类方法:

allow(DiscordClient).to receive(:get_guild)

您将发现此模式在服务对象中广泛使用.

Ruby-on-rails相关问答推荐

本地主机的上衣配置

Rails:比枚举更惯用的排序/可比较列表方法?

获取所有属于模型的嵌套对象

具有 IN 子句的参数化查询在 ruby​​-on-rails 的 blazer 工具中无法按预期工作

Rails 7 应用程序 - 引用模型文件时出现未初始化常量错误

如何为 I18n 设置 raise_on_missing_translations

Ruby on Rails 有没有好的管理生成器?

Rails 4.1 Mailer 预览和设计自定义邮箱

jQuery ajax 请求不会触发 Rails 控制器的 JS 响应?

如何在where子句中组合两个条件?

如何将 yaml 文件解析为 ruby​​ 哈希和/或数组?

没有图像时如何在回形针中显示隐藏图像

什么是 Ruby 中的 Python 文档字符串?

将根 url 重定向到 Rails 应用程序中的其他位置

如何让空白复选框作为假传递给参数

Rails:使用 link_to 创建不带 href 的链接

加载常量时自动加载常量时检测到循环依赖

如何跳过失败的迁移? (耙分贝:迁移)

默认情况下 haml

在 GIT 中处理 Rails db/schema.rb 文件的正确方法是什么?