RSpe c Mock - класс не реализует метод экземпляра: jql. Возможно, вы хотели использовать вместо этого `class_double`? - PullRequest
0 голосов
/ 18 февраля 2020

Я хочу смоделировать метод, который использует Jira- Ruby gem с 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 класс не реализует метод экземпляра: jql. Возможно, вы хотели использовать class_double вместо этого?

1 Ответ

0 голосов
/ 26 февраля 2020

Несколько вещей:

  • Вы используете синтаксис насмешки для значений c, а не объектов. Мой ответ на ваш другой вопрос здесь должен помочь: { ссылка } IMO, использование instance_double здесь хорошо, потому что вы - насмешливые экземпляры, хотя, если вы собираетесь вызывать методы смоделированного объекта, вам часто нужно определить их ответы в объявлении instance_double (как упомянуто в моем связанном комментарии).
  • Будьте осторожны с проверкой издевательского поведения; вам нужно только проверить, что клиентский объект создан с определенными опциями и что jql вызывается с указанными c аргументами (то есть убедитесь, что вы проверяете поведение своего кода на предмет прерывания изменений, а не поведения гема ).
  • Ваша спецслужба c проверяет, что call возвращает project, но вы нигде не определили или не высмеяли это?
  • Вы также определяете issue_factory и issue как 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) }

...