Использование дорогостоящего метода с помощью Rspec - PullRequest
0 голосов
/ 30 августа 2018

В приведенном ниже примере я просто хочу передать хэш в двойной тестовый объект. Я не хочу проверять двойное само по себе. Но мне нужно подражать в моем тесте. Фактический метод выглядит примерно так:

# user.rb
def do_work
  assignments = fetch_assignments
  if assignments.any?
    assignments.each do |assignment|
      if assignment.valid?
        client.approve_assignment({assignment_id: assignment.assignment_id})
      else
        client.reject_assignment({assignment_id: assignment.assignment_id})
      end
    end 

    mark_assignments_as_complete    
  end
end

Теперь я могу легко протестировать все функции, кроме клиента. Клиент - это очень дорогой (и требует денег на запрос) API-запрос, который я не хочу запускать каждый раз, когда запускаю тест. Поэтому я использую тестовые двойники и заглушки:

describe "#do_work" do
  context "when two assignments are valid" do
    before :context do
      @user = User.create!({name: "Bob"})
      [{assignment_id: "1", valid: false}, {assignment_id: 2, valid: false}, {assignment_id: "3", valid: true}].each do |assignment|
        @user.assignments.create!(assignment)
      end
      @client = ExpensiveAPI.new
      @user.client = @client
    end
  end

  describe "#do_work" do
    it "accepts valid assignments" do
      user.valid_assignments.each do |assignment|
        allow(@client).to receive(:accept_assignment, {assignment_id: assignment.assignment_id}).and_return(true)
      end

      expect(@user.do_work).to have 2_completed_assignments
    end

    it "rejects invalid assignments" do
      user.valid_assignments.each do |assignment|
        allow(@client).to receive(:accept_assignment, {assignment_id: assignment.assignment_id}).and_return(true)
      end

      expect(@user.do_work).to have 1_incomplete_assignment
    end
  end
end

Когда я пытаюсь передать аргумент в метод stubbed, я получаю эту ошибку:

ArgumentError: wrong number of arguments (2 for 1)

1 Ответ

0 голосов
/ 30 августа 2018

Я думаю, что это проблема синтаксиса. Формат для заглушки метода с аргументами (согласно https://relishapp.com/rspec/rspec-mocks/v/2-99/docs/method-stubs):

allow (obj) .to получать (: message) .with ('аргумент') {...}

Но вы передаете ожидаемые аргументы в качестве вторичного аргумента для получения (...), поэтому он жалуется, что он принимает только 1 аргумент.

Измените свою спецификацию на:

describe "#do_work" do
  context "when two assignments are valid" do
    before :context do
      @user = User.create!({name: "Bob"})
      [{assignment_id: "1", valid: false}, {assignment_id: 2, valid: false}, {assignment_id: "3", valid: true}].each do |assignment|
        @user.assignments.create!(assignment)
      end
      @client = ExpensiveAPI.new
      @user.client = @client
    end
  end

  describe "#do_work" do
    it "accepts valid assignments" do
      user.valid_assignments.each do |assignment|
        allow(@client).to receive(:accept_assignment).with({assignment_id: assignment.assignment_id}).and_return(true)
      end

      expect(@user.do_work).to have 2_completed_assignments
    end

    it "rejects invalid assignments" do
      user.valid_assignments.each do |assignment|
        allow(@client).to receive(:accept_assignment).with({assignment_id: assignment.assignment_id}).and_return(true)
      end

      expect(@user.do_work).to have 1_incomplete_assignment
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...