Rails集成测试创建会话时遇NoMethodError问题求助
集成测试中创建登录会话时出现NoMethodError错误
执行集成测试时,创建用户登录会话失败,报错如下:
Finished tests in 0.273092s, 3.6618 tests/s, 0.0000 assertions/s. 1) Error: ListCategoriesTest#test_should_create_category: NoMethodError: undefined method `[]' for nil:NilClass app/controllers/session_controller.rb:8:in `create' test/test_helper.rb:16:in `sign_in_as' test/integration/list_categories_test.rb:20:in `block in <class:ListCategoriesTest>'
集成测试文件(test/integration/list_categories.rb)
require 'test_helper' class ListCategoriesTest < ActionDispatch::IntegrationTest def setup @category=Category.create(name: "Sports") @admin_user = User.create(username: "fardeen", email: "fardeenmhs@hotmail.com", password: "fardeen", admin: true) end test "should create category" do sign_in_as(@admin_user) assert_difference('Category.count',1) do post :create, category: { name:"Travel" } end assert_redirected_to category_path(Category.last) end end
测试辅助函数(test/test_helper.rb)
ENV["RAILS_ENV"] ||= "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' class ActiveSupport::TestCase ActiveRecord::Migration.check_pending! fixtures :all def sign_in_as(user) post login_path, params:{ session:{"email"=> user.email, "password"=> "fardeen"} } end end
Session控制器(app/controllers/session_controller.rb)
class SessionController < ApplicationController def new render 'new' end def create user=User.find_by(email: params[:session][:email].downcase) if user and user.authenticate(params[:session][:password]) flash[:info]="You have been successfully logged in!!!" session[:user_id]=user.id redirect_to user else flash[:notice]="Invalid Creds!!!" render 'new' end end def destroy session[:user_id]=nil flash[:info]="You have been logged out!!!" redirect_to users_path end end
已尝试的解决方法及结果
我尝试过多种传参形式,但都未能解决问题:
- 调整sign_in_as方法的传参格式:
post login_path, "session"=>{"email"=> user.email, "password"=> "fardeen"}
无效果,仍报错。
- 尝试分开传递params和session:
post login_path, params:{}, session:{"email"=> user.email, "password"=> "fardeen"}
出现新错误:
1) Error: ListCategoriesTest#test_should_create_category: ArgumentError: bad argument (expected URI object or URI string) test/integration/list_categories_test.rb:22:in `block (2 levels) in <class:ListCategoriesTest>' test/integration/list_categories_test.rb:21:in `block in <class:ListCategoriesTest>'
对应的日志:
ListCategoriesTest: test_should_create_category ----------------------------------------------- (1.0ms) SAVEPOINT active_record_1 Category Exists (0.0ms) SELECT 1 AS one FROM "categories" WHERE "categories"."name" = 'Sports' LIMIT 1 SQL (28.1ms) INSERT INTO "categories" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Sat, 19 Aug 2023 15:30:44 UTC +00:00], ["name", "Sports"], ["updated_at", Sat, 19 Aug 2023 15:30:44 UTC +00:00]] (0.0ms) RELEASE SAVEPOINT active_record_1 (0.0ms) SAVEPOINT active_record_1 (0.0ms) ROLLBACK TO SAVEPOINT active_record_1 Started POST "/login" for 127.0.0.1 at 2023-08-19 21:00:44 +0530 Processing by SessionController#create as HTML Parameters: {"params"=>{"session"=>{"email"=>"fardeenmhs@hotmail.com", "password"=>"[FILTERED]"}}} Completed 500 Internal Server Error in 41ms (3.0ms) rollback transaction
- 尝试简化传参:
def sign_in_as(user) post login_path, { session: { email: user.email, password: "fardeen" } } end
日志显示参数已传递,但登录验证失败,页面重新渲染登录页:
Started POST "/login" for 127.0.0.1 at 2023-08-21 22:14:59 +0530 Processing by SessionController#create as HTML Parameters: {"session"=>{"email"=>"fardeenmhs@hotmail.com", "password"=>"[FILTERED]"}} User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'fardeenmhs@hotmail.com' LIMIT 1 Rendered users/_footer.html.erb (0.0ms) Rendered session/new.html.erb within layouts/application (2.0ms) Rendered layouts/_messages.html.erb (0.0ms) Completed 200 OK in 8ms (Views: 6.0ms | ActiveRecord: 0.0ms) (0.0ms) SELECT COUNT(*) FROM "categories" (3.0ms) rollback transaction
核心疑问
我无法理解为什么会出现参数为nil的情况,或者说session哈希无法通过POST请求正确传递?
内容的提问来源于stack exchange,提问作者Fardeen
相关产品推荐
相关产品推荐

