ruby-on-rails - Rspec login_user 问题
问题描述
我在使用 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 以及上部块)
我的控制器宏:
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)
.
如果您查看设备文档,您还会看到它在 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
我喜欢的方式:
在您的控制器宏中,将 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
推荐阅读
- pyspark - 如何在 pyspark 中解压 tar.gz 文件?tar.gz 中有 10 个文件。我有兴趣只阅读 10 个文件中的一个
- python - pivot_table 中的错误:Dropna=False:数组太大;`arr.size * arr.dtype.itemsize` 大于最大可能大小
- javascript - HTML CSS JS,无法打开我制作的实时代码编辑器
- javascript - 如何随机替换特定 URL 的 HREF?innerHTML 影响延迟加载
- pandas - 从日期范围中删除几个日期
- django - 芹菜时间表
- android - 如何拦截Android中的所有onClick事件?
- string - 如何从 Rust 中的另一个字符串中删除单个尾随字符串?
- c# - 来自测试的 Autofac RegisterAssemblyTypes
- pdf - Netsuite 发票 Pdf 显示应用金额