Rspec login_user проблема - PullRequest
0 голосов
/ 29 июня 2019

У меня проблема с входом пользователя в Devise / Rspec для поиска маршрута для тестирования.Я использовал модуль support/controller_macros, как описано devise, но всякий раз, когда я пытаюсь использовать login_user в любой части моего теста, я получаю сообщение об ошибке: before is not available from within an example (e.g. an it block) or from constructs that run in the scope of an example (e.g. before, let, etc). It is only available on an example group (e.g. a describe or context block).

Я пытался что-то изменитьубедиться, что все мои требования настроены правильно и т. д.

Мой тест:

require "rails_helper"

RSpec.describe BallotsController, type: :controller do
  describe "index" do
    it "renders" do
      login_user
      ballots_path
      expect(response).to be_success
      expect(response).to render_template("index")
    end
  end
end

(я попытался добавить login_user внутри блока описания, а также в верхний блок)

Мой контроллер_macros:

  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user_confirmed]
      user = FactoryBot.create(:user_confirmed)
      sign_in user
    end
  end

  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      user = FactoryBot.create(:admin)
      sign_in user
    end
  end
end

Мой помощник по спецификациям:

require "rails_helper"
require_relative "support/controller_macros"
RSpec.configure do |config|
  # rspec-expectations config goes here. You can use an alternate
  # assertion/expectation library such as wrong or the stdlib/minitest
  # assertions if you prefer.
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end

  config.shared_context_metadata_behavior = :apply_to_host_groups
  config.include ControllerMacros, :type => :controller
  config.include Devise::Test::ControllerHelpers, :type => :controller

  config.example_status_persistence_file_path = "spec/examples.txt"

  config.disable_monkey_patching!

  if config.files_to_run.one?
    config.default_formatter = "doc"
  end

  config.profile_examples = 10

  config.order = :random

  Kernel.srand config.seed
end

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

1 Ответ

1 голос
/ 29 июня 2019

Единственная проблема в коде (чтобы устранить ошибку, не углубляясь в дискуссию о том, следует ли использовать этот метод), состоит в том, что у вас есть логин пользователя в блоке it, чего не может быть, потому что это звонить before(:each).

Если вы увидите документацию по устройству , вы также увидите, что у него нет этого вызова в этом блоке, а скорее вне его в блоке описания. Который применяет этот вызов ко всем блокам в этом блоке описания.

Ваш код станет:

RSpec.describe BallotsController, type: :controller do
  describe "index" do
    login_user
    it "renders" do
      ballots_path
      expect(response).to be_success
      expect(response).to render_template("index")
    end
  end
end

Как я предпочитаю:

В вашем controller_macros замените login_user на:

def login_user(user)
  @request.env["devise.mapping"] = Devise.mappings[:user_confirmed]
  sign_in user
end

Теперь, куда бы вы ни захотели войти, вы можете сделать что-то вроде:

RSpec.describe BallotsController, type: :controller do
  describe "index" do
    let(:user) { FactoryBot.create(:user) }

    it "renders" do
      login_user(user)
      ballots_path
      expect(response).to be_success
      expect(response).to render_template("index")
    end
  end

  # OR

  describe "index" do
    let(:user) { FactoryBot.create(:user) }

    before(:each) do
      login_user(user)
    end

    it "renders" do
      ballots_path
      expect(response).to be_success
      expect(response).to render_template("index")
    end
  end
end
...