【问题标题】:Accessing session in integration test在集成测试中访问会话
【发布时间】:2017-06-09 15:04:35
【问题描述】:

我是一名 Rails 初学者,正在阅读 Michael Hartl 的 Rails 教程,但收到一个错误,我不知道如何解决。作为参考,这是为了实现清单 9.24 (https://www.railstutorial.org/book/advanced_login) 中的更改。

我跳过了第 9 章(因为它被认为是可选的),但在第 10 章中它要求包含清单 9.24 中所做的更改,所以我这样做了,但我的测试仍然失败。

这是我在运行 rails test 时收到的错误

Error:
UsersEditTest#test_unsuccessful_edit:
NoMethodError: undefined method `session' for nil:NilClass
    test/test_helper.rb:18:in `log_in_as'
    test/integration/users_edit_test.rb:14:in `block in <class:UsersEditTest>'


bin/rails test test/integration/users_edit_test.rb:12

E

Error:
UsersEditTest#test_successful_edit:
NoMethodError: undefined method `session' for nil:NilClass
    test/test_helper.rb:18:in `log_in_as'
    test/integration/users_edit_test.rb:28:in `block in <class:UsersEditTest>'

失败的测试(在 test/integration/users_edit_test.rb 中)是:

test "successful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
... end
test "unsuccessful edit" do
     log_in_as(@user)
    get edit_user_path(@user)
... end

这里是被调用的 integration/test_helper 方法

# Log in as a particular user.
  def log_in_as(user)
    session[:user_id] = user.id
  end

特别令人困惑的是,测试助手中有另一种方法也使用会话,并且在 user_login_test 中调用它可以正常工作。

任何帮助将不胜感激!

【问题讨论】:

    标签: ruby-on-rails ruby testing integration-testing railstutorial.org


    【解决方案1】:

    为了将来遇到此问题的任何人的利益,对于集成测试,您需要定义一个 test_helper 方法,该方法发布到会话控制器的创建方法,而不是专门修改会话,例如

    class ActionDispatch::IntegrationTest
        def log_in_as(user, password: 'password')
            post login_path, params: { session: { email: user.email, password: password} }
        end
    end
    

    您的其他会话方法起作用的原因是它没有为会话哈希分配任何内容,只是检查值是否存在。对于集成测试,您不能直接永久修改会话哈希。

    【讨论】:

      【解决方案2】:

      会话仅在测试用例中第一次请求后可用。您的 log_in_as(user) 辅助方法可以启动实际登录用户的请求,以便会话将被 user.id 填充。

      查看此线程中的讨论:

      https://github.com/rails/rails/issues/23386#issuecomment-192954569

      【讨论】:

        【解决方案3】:

        这就是我为 Rails 6 做的:

        test_helper.rb添加了一个助手:

        # test_helper.rb
        ENV['RAILS_ENV'] ||= 'test'
        require_relative "../config/environment"
        require "rails/test_help"
        
        class ActiveSupport::TestCase
          # Run tests in parallel with specified workers
          parallelize(workers: :number_of_processors)
        
          # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
          fixtures :all
        
          # Add more helper methods to be used by all tests here...
          def sign_in_as(user, password)
            post sessions_url, params: { email: user.email, password: password }
          end
        end
        

        这是users_controller_test.rb 中的一个测试示例:

        test "should show user" do
          sign_in_as(@user, 'password')
        
          get user_url(@user)
          assert_response :success
        end
        

        根据表单的结构,您可能需要将凭据包装在 :sessions 哈希中。检查当您的表单在页面上呈现时,name 属性中是否有 session[email]

        <input type="text" name="session[email]" id="email">
        

        如果是这种情况,请更改 sign_in_as 方法以在 :params 中解决此问题:

        def sign_in_as(user, password)
          post sessions_url, params: { session: { email: user.email, password: password } }
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-30
          • 2017-11-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多