ruby - RSpec Mock - 类未实现实例方法 : jql. 也许您打算改用 `class

我想模拟使用 Jira-Ruby gem with jql lib 的方法

def call
  client = JIRA::Client.new(options)
  client.Issue.jql(
    "project = #{project_key} AND
    status != Done AND
    status != Closed AND
    status != Cancelled AND
    status != Followup",
    query_options
  )
end

我的模拟:

  let(:jql_options) do
    [
      "project = TSW-123 AND
      status != Done AND
      status != Closed AND
      status != Cancelled AND
      status != Followup",
      query_options
    ]
  end
  let(:query_options) do
    {
      start_at: 0,
      max_results: 1000
    }
  end
  let(:jira_client) { instance_double(JIRA::Client) }
  let(:issue) { instance_double(JIRA::Resource::Issue) }
  let(:issue_factory) { instance_double(JIRA::Resource::Issue) }

  before do
    allow(JIRA::Client).to receive(:new).with(options).and_return(jira_client)
    allow(jira_client).to receive(:Issue).and_return(issue_factory)
    allow(issue_factory).to receive(:jql).with(*jql_options).and_return(issue)
  end

  it 'connect to the project' do
    expect(subject.call).to eq(project)
  end

我收到一个错误:

JIRA::Resource::Issue class does not implement the instance method: jql. Perhaps you meant to use class_double instead?

最佳答案

一些事情:

  • 您正在对静态值而非对象使用模拟语法。我在这里对您的其他问题的回答应该有所帮助:https://stackoverflow.com/a/60404227/4024628 IMO,在这里使用 instance_double 很好,因为您正在模拟实例,但如果您要调用模拟对象的方法,您通常需要在 instance_double 声明中定义它们的响应(如我的链接评论中所述)。
  • 谨慎测试模拟行为;您应该只需要测试客户端对象是使用某些选项创建的,并且 jql 是使用特定参数调用的(意思是,确保您正在验证代码的行为以防止破坏性更改 - 而不是 gem 的行为)。
  • 您的规范正在测试 call 返回 project,但您还没有在任何地方定义或模拟它?
  • 您还将 issue_factoryissue 定义为同一类的 instance_doubles,这与您正在使用的类的文档不一致(打字错误?)。

这样的事情可能就足够了:

# You should always name your subject if you are calling methods on it
subject(:instance) { described_class.new }

let(:client)        { instance_double(JIRA::Client)
let(:issue_factory) { instance_double(JIRA::Resource::IssueFactory) }
# This likely needs to be an OpenStruct instead since docu says it returns an obj
let(:project)       { instance_double(JIRA::Resource::Project) }

before do 
  allow(client).to receive(:new).with(options)  { client }
  allow(client).to receive(:Issue) { issue_factory }
  allow(issue_factory).to receive(:jql).with(*jql_options) { project }
end

it 'creates client with correct options' do 
  expect(client).to receive(:new).with(options) 
  instance.call
end

it 'calls #jql with correct options' do
  expect(issue_factory).to receive(:jql).with(*jql_options)
  instance.call
end

it { expect(instance.call).to eq(project) }

关于ruby - RSpec Mock - 类未实现实例方法 : jql. 也许您打算改用 `class_double`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60279872/

相关文章:

java - 如何将不同大小的元素立即放在彼此之上?

css - 使用 attr() 更新 CSS 变量

google-cloud-platform - Terraform 0.12 使用模板创建入口规则

azure-devops - 在 Azure Devops 中编写 EF6 迁移脚本

python - 如何在 TensorFlow 2 中保存/加载模型的一部分?

typescript - TypeScript 中的非破坏性类型断言

django - 使用 DjangoFilterConnectionField 时有没有办法删除边和

android - 蓝牙扫描设备,频繁扫描后无法写入设备

node.js - 谷歌 API + Passport + react : Authenticati

html - 什么决定了 Firefox 中的滚动条是否有颜色?