【问题标题】:Rails integration test with the devise gem使用设计 gem 进行 Rails 集成测试
【发布时间】:2010-11-27 17:20:23
【问题描述】:

我想编写一个 Rails 集成测试(使用 ActionDispatch::IntegrationTest)。我正在使用设计进行身份验证,并使用机械师进行测试模型。我无法成功登录。

这是一个简单的例子:

class UserFlowsTest < ActionDispatch::IntegrationTest
  setup do
    User.make
  end
  test "sign in to the site" 
    # sign in
    post_via_redirect 'users/sign_in', :email => 'foo@bar.com', :password => 'qwerty'    
    p flash
    p User.all
end

这是调试输出:

Loaded suite test/integration/user_flows_test
Started
{:alert=>"Invalid email or password."}
[#<User id: 980190962, email: "", encrypted_password: "", password_salt: "", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2010-11-27 16:44:10", updated_at: "2010-11-27 16:44:10">, #<User id: 980190963, email: "foo@bar.com", encrypted_password: "$2a$10$vYSpjIfAd.Irl6eFvhJL0uAwp4qniv5gVl4O.Hnw/BUR...", password_salt: "$2a$10$vYSpjIfAd.Irl6eFvhJL0u", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2010-11-27 17:09:13", updated_at: "2010-11-27 17:09:13">]
"/unauthenticated"
F

这是我的蓝图.rb:

require 'machinist/active_record'
require 'sham'

User.blueprint do
  email {"foo@bar.com"}
  password {"qwerty"}
end

【问题讨论】:

标签: ruby-on-rails integration-testing devise machinist


【解决方案1】:

它不起作用的原因是设计将表单字段名称创建为

'user[email]'
'user[password]'

并且 post_via_redirect 期望这些名称作为参数。因此,以下语句将成功登录。

post_via_redirect 'users/sign_in', 'user[email]' => 'foo@bar.com', 'user[password]' => 'qwerty' 

【讨论】:

  • 以防万一它有帮助 - 在我的情况下,因为它是 JSON 的集成测试,只有 post_via_redirect 'users/sign_in', user: { email: "foo@bar.com", password: "qwerty" }, format: :json 有效。
【解决方案2】:

首先,使用设计,您可能必须“确认”用户。

你可以这样做:

user = User.make!
user.confirmed_at = Time.now
user.save!

这是一个没有机械师的例子(但你只需要用上面的部分替换用户创建代码部分):

进入 test_integration_helper:

require "test_helper"
require "capybara/rails"

    module ActionController
      class IntegrationTest
        include Capybara

        def sign_in_as(user, password)
           user = User.create(:password => password, :password_confirmation => password, :email => user)
           user.confirmed_at = Time.now 
           user.save!
           visit '/'
           click_link_or_button('Log in')
           fill_in 'Email', :with => user.email
           fill_in 'Password', :with => password
           click_link_or_button('Sign in')
           user      
         end 
         def sign_out
            click_link_or_button('Log Out')   
         end
      end
    end

然后进入您的集成测试:

require 'test_integration_helper'

class UsersIntegrationTest < ActionController::IntegrationTest

  test "sign in and then sign out" do 
    #this helper method is into the test_integration_helper file                   
    sign_in_as("lolz@gmail.com", "monkey")         
    assert page.has_content?('Signed in successfully'), "Signed in successfully"

    sign_out         
    assert page.has_content?('Signed out successfully'), "Signed out successfully" 
  end
end

【讨论】:

  • 感谢您的回复。我将不得不再次挖掘那个项目,看看它是如何工作的。暂时 +1。
【解决方案3】:

由于您使用的是ActionDispatch::IntegrationTest,因此您可以包含Devise::Test::IntegrationHelpers 模块并改用sign_in 方法(您可以将用户传递给该方法):

class UserFlowsTest < ActionDispatch::IntegrationTest
  include Devise::Test::IntegrationHelpers

  test "sign in to the site" do
    sign_in users(:one)
  end
end

【讨论】:

    【解决方案4】:

    我在书中没有针对 Devise 的示例集成测试,但我认为如果您安装了 Webrat/Capybara,Cucumber 章节中步骤定义中的代码也可以使用:

    @user = User.create!(:email => "email@email.com",  
                :password => "password",  
                :password_confirmation => "password")
    visit "login"  
    fill_in("user_email", :with => @user.email)  
    fill_in("user_password", :with => "password") 
    click_button("Sign In")
    

    【讨论】:

    • 感谢您的回复。我将不得不再次挖掘那个项目,看看它是如何工作的。暂时+1。另外,感谢您的阅读:)
    【解决方案5】:

    如果其他人有类似的问题...

    我处于类似的情况(从 Authlogic 迁移),并且遇到了完全相同的问题。问题出在 devise.rb 初始化程序中。默认情况下,它会将您的测试环境设置为在密码的加密/解密期间仅使用 1 段。老实说,我不知道什么是延伸,但要让设计使用旧的 Authlogic 加密密码,延伸必须是 20。因为我试图登录一个最初在我的测试中使用 Authlogic 加密密码的用户,设计也需要在测试中使用 20 次拉伸。我更改了如下配置:

    # Limiting the stretches to just one in testing will increase the performance of
    # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
    # a value less than 10 in other environments.
    -  config.stretches = Rails.env.test? ? 1 : 20
    +  config.stretches = 20
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多