InstanceDouble (session) (anonymous)> получил неожиданное сообщение: [] = с - PullRequest
1 голос
/ 07 апреля 2019

У меня проблема с поведением rspec. Я пытаюсь написать тест для службы, где я использую session, для чтения некоторого значения и перезаписать это значение.

Например, что я хочу проверить

class CurrentCartService
  attr_reader :user, :session

  def initialize(user, session)
    @user = user
    @session = session
  end

  def cart_id
    { id: session[:cart_id] }
  end

  def assigne_cart_to_session
    session[:cart_id] = current_cart.id
  end

spec

describe CurrentCartService do
  let(:current_user) { user }
  let(:session) { double('session') }

  let!(:cart) { create(:cart) }

  subject { described_class.new current_user, session }

  before do
    allow(session).to receive(:[]).and_return(cart.id)
  end

  describe '#call' do
    context 'when user is not signed' do
      let(:user) { nil }
      it { subject.call }
    end
  end
end

binding.pry

session[:cart_id]
=> 574
session[:cart_id] = 123
RSpec::Mocks::MockExpectationError: #<InstanceDouble(session) (anonymous)> received unexpected message :[]= with (:cart_id, 123)

Как это исправить? Я пытался написать некоторые expect

expect(session).to receive(:[])

Но это не работает, это все та же ошибка

1 Ответ

0 голосов
/ 07 апреля 2019

В сообщении говорится, что ваш двойник получил сообщение []= с аргументами :cart_id и 123, но не ожидал этого.

Давайте применим некоторую базовую логику.Проблема в том, что

  1. получает сообщение
  2. , которое не ожидалось

Итак, есть две вещи, которые вы можете сделать, чтобы избавиться отсообщение:

  1. не отправлять сообщение ИЛИ
  2. сообщить двойнику, что следует ожидать сообщения

Первый способ прост: просто удалите строку 14, в которой написаноsession[:cart_id] = current_cart.id, так как это единственное место, куда вы звоните []=.Тем не менее, я не думаю, что это то, что вы хотите сделать.

Номер два также легко.Существует метод с именем expect, который позволяет вам указать двойное число, чтобы ожидать определенного сообщения.Итак, все, что нам нужно сделать, это настроить ожидание.

Хорошие сообщения об ошибках действительно важны в среде тестирования, и, к счастью, RSpec имеет хорошие сообщения об ошибках.В сообщении об ошибке должно быть указано, как двигаться дальше с вашими тестами, а в сообщении, которое вы цитировали, содержится вся необходимая нам информация:

  • имя двойника, вызвавшего ошибку (session)
  • имя неожиданного сообщения, вызвавшего сбой ([]=)
  • и даже аргументы, которые были переданы сообщению (:cart_id и 123)

Все, что нам нужно сделать, это, даже не задумываясь об этом, буквально просто скопировать и вставить эту информацию:

expect(session).to receive(:[]=).with(:cart_id, 123)

Или, если мы хотим, чтобы наши тесты были немного менее хрупкими и не имели жесткого кода123, мы также можем сделать что-то вроде этого:

expect(session).to receive(:[]=).with(:cart_id, instance_of(Integer))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...