Rspec login_user 问题
Rspec login_user issue
我在使用 Devise/Rspec 登录用户以点击测试路线时遇到问题。我按照设计概述使用了 support/controller_macros
模块,但每当我尝试使用
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
(我试过在 describe 块和上面的块中添加 login_user)
我的controller_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
我希望它能让用户登录,并让控制器正确命中索引路由。谢谢!
代码中唯一的问题(解决错误,而不深入讨论是否应该使用此方法)是您在 it
块中有登录用户,这不能是因为它正在调用 before(:each)
.
如果您看到 device documentation,您还会看到它在 it 块中没有此调用,而是在 it 块之外的 describe 块中。它将此调用应用于该描述块中的所有 it 块。
您的代码将变为:
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
我在使用 Devise/Rspec 登录用户以点击测试路线时遇到问题。我按照设计概述使用了 support/controller_macros
模块,但每当我尝试使用
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
(我试过在 describe 块和上面的块中添加 login_user)
我的controller_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
我希望它能让用户登录,并让控制器正确命中索引路由。谢谢!
代码中唯一的问题(解决错误,而不深入讨论是否应该使用此方法)是您在 it
块中有登录用户,这不能是因为它正在调用 before(:each)
.
如果您看到 device documentation,您还会看到它在 it 块中没有此调用,而是在 it 块之外的 describe 块中。它将此调用应用于该描述块中的所有 it 块。
您的代码将变为:
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