RSpec как заглушить урожай и не дать ему убедиться - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть действие action_action вокруг set_current_user

def set_current_user
  CurrentUser.set(current_user) do
    yield
  end
end

В синглтоне CurrentUser

  def set(user)
    self.user = user
    yield
  ensure
    self.user = nil
  end

Я не могу понять, как заглушить урожай, и не могучасть метода под названием

В идеале я хотел бы сделать что-то вроде

it 'sets the user' do
  subject.set(user)
  expect(subject.user).to eql user
end 

Две ошибки я получаю

    1. Нет блокадается
  • Когда я передаю блок, self.user = nil вызывается

Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 09 декабря 2018

Я не упомянул, что мне нужно очищать пользователя после каждого запроса.

Это то, что я придумал.Это своего рода сумасшествие - помещать ожидание в лямбду, но он гарантирует, что пользователь настроен до обработки запроса и очищает его после

describe '.set' do
  subject { described_class }

  let(:user) { OpenStruct.new(id: 1) }

  let(:user_expectation) { lambda{ expect(subject.user).to eql user } }

  it 'sets the user prior to the block being processed' do
    subject.set(user) { user_expectation.call }
  end

  context 'after the block has been processed' do
    # This makes sure the user is always cleared after a request
    # even if there is an error and sidekiq will never have access to it.

    before do
      subject.set(user) { lambda{} }
    end

    it 'clears out the user' do
      expect(subject.user).to eql nil
    end
  end
end
0 голосов
/ 10 декабря 2018

Я не уверен, что вы намерены выполнить с этим, так как кажется, что вы просто хотите убедиться, что user установлен в блоке и не установлен впоследствии.Если это так, то следующее должно работать нормально

class CurrentUser
  attr_accessor :user
  def set(user)
    self.user = user
    yield
  ensure
    self.user = nil
  end
end

describe '.set' do
  subject { CurrentUser.new }
  let(:user) { OpenStruct.new(id: 1) }
  it 'sets user for the block only' do 
    subject.set(user) do 
      expect(subject.user).to eq(user)
    end 
    expect(subject.user).to be_nil 
  end
end

Это проверит, что внутри блока (где вызывается yield), что subject.user равно user, а затем subject.userноль.

Выход :

.set
  sets user for the block only

Finished in 0.03504 seconds (files took 0.14009 seconds to load)
1 example, 0 failures
0 голосов
/ 09 декабря 2018

Несколько замечаний, которые могут помочь:

ensure зарезервировано для блока кодов, который вы хотите запустить независимо от того, что произойдет, поэтому причина, по которой ваш self.user всегда будет nil.Я думаю, что вы хотите, чтобы назначить пользователя на ноль, если есть исключение.В этом случае вместо этого следует использовать rescue.

def set(user)
  self.user = user
  yield
rescue => e
  self.user = nil
end

Что касается модульного теста, то вам нужно протестировать только метод .set в классе CurrentUser.Предполагая, что у вас все правильно подключено в вашем окружающем фильтре, вот пример, который может вам помочь:

describe CurrentUser do
  describe '.set' do
    let(:current_user) { create(:user) } 
    subject do
      CurrentUser.set(current_user) {}
    end
    it 'sets the user' do
      subject
      expect(CurrentUser.user).to eq(current_user)
    end 
  end
end

Надеюсь, это поможет!

...