首页 > 解决方案 > 选择循环内的 RSpec 模拟方法

问题描述

我想测试一个简单的类,它遍历哈希数组并只返回那些状态为 Pending 的类,这些类在 2 天前更新。

  class FetchPending
    PROJECT_KEY = 'TPFJT'
    TWO_DAYS = Time.now - 2 * 24 * 60 * 60

    def call
      project.select do |issue|
        issue.fields.dig('status', 'name') == 'Pending' &&
          DateTime.parse(issue.fields.dig('updated')) < TWO_DAYS
      end
    end

    private

    def project
      @project ||= Jira::ProjectConnection.new(PROJECT_KEY).call
    end
  end

如何测试Jira-Ruby gemfields的方法。我认为它来自这里(gem 资源中的字段类),因为我在其他任何地方都找不到方法。fields

以下是我调试后的想法:

我的自然想法是:

  before do
    # (...) some other mocks
    allow(JIRA::Resource::Issue).to receive(:fields)
  end

但我收到一个错误:

失败/错误:allow(JIRA::Resource::Issue).to receive(:fields)

JIRA::Resource::Issue 未实现:字段

几天来我一直在努力解决这个问题,我在这里非常绝望。如何模拟这种方法?

这是我的其余规格:

RSpec.describe FetchPending do
  subject { described_class.new }

  let(:project_hash) do
    [
      {
        'key': 'TP-47',
        'fields': {
          'status': {
            'name': 'Pending'
          },
          'assignee': {
            'name': 'michael.kelso',
            'emailAddress': 'michael.kelso@example.com'
          },
          'updated': '2020-02-19T13:20:50.539+0100'
        }
      }
    ]
  end
  let(:project) { instance_double(Jira::ProjectConnection) }

  before do
    allow(Jira::ProjectConnection).to receive(:new).with(described_class::PROJECT_KEY).and_return(project)
    allow(project).to receive(:call).and_return(project_hash)
    allow(JIRA::Resource::Issue).to receive(:fields)
  end

  it 'return project hash' do
    expect(subject.call).include(key[:'TP-47'])
  end

标签: rubyrspecmocking

解决方案


and_return通常用于返回一个值(例如字符串或整数)或值序列,但对于有时需要使用的对象。此外,如果call是返回 project_hash 值的对象上的有效方法Jira::ProjectConnection,您可以在声明您的实例 double 时直接模拟其行为(Relish 文档中不清楚此功能,因为它们有点糟糕)。这样的事情可能会起作用:

let(:project) { instance_double(Jira::ProjectConnection, call: project_hash) }

before do
  # Ensure new proj conns always return mocked 'project' obj
  allow(Jira::ProjectConnection).to receive(:new).with(
    described_class::PROJECT_KEY
  ) { project }
end

如果还是不行,尝试暂时替换described_class::PROJECT_KEYanything调试;这可以帮助您确认是否指定了错误的 arg(s) 被发送到new.

关于错误消息,看起来 JIRA::Resource::Issue没有fields属性/方法,但fields似乎嵌套在attrs? 该JIRA::Resource::Project#issues方法还将 JSON 中的问题转换为问题对象,因此如果您使用该方法,则需要更改project_hash.


推荐阅读