如何在Rails4测试中使用Devise登录/注销用户 [英] How to log in/out users with Devise in Rails4 testing

查看:607
本文介绍了如何在Rails4测试中使用Devise登录/注销用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在努力确保在Rails 4中使用Devise进行适当的用户访问,而且我很难在测试套件中记录用户。 p>最简单的情况:

  require'test_helper'
include Devise :: TestHelpers

class SiteLayoutTest< ActionDispatch :: IntegrationTest

def setup
@user = users(:test1)
end

测试登录应该获得索引do
sign_in @user
get users_path
assert_response:success
assert_selecttitle,User Index
end
end

到目前为止,我没有做的更多,而不仅仅是使用适当的操作实现Devise和Users控制器。



我一直得到: NoMethodError:未定义的方法'env'为nil:NilClass ,具体指的是包含 sign_in @user ,我可以找到其他人发生相同错误的实例,但似乎并没有找到我正在尝试解决的问题的实际解决方案。 >

如何使用Rails 4中的Devise登录用户进行测试?谢谢。



编辑:



fixtures / users.yml

  test1:
id:'1'
电子邮件:'test1@example.com'
encrypted_pa​​ssword:<%= Devise :: Encryptor.digest(User,password)%>
created_at:<%= Time.now - 6.minutes%>
updated_at:<%= Time.now - 4.minutes%>

解决方案在SITU:

 测试登录应该得到索引do 
post user_session_path,'user [email]'=> @ user.email,'user [password]'=> 'password'
get users_path
assert_response:success
assert_selecttitle,User Index
end


解决方案

这是从他们的 docs


在集成测试中不要使用Devise :: TestHelpers。 / p>

您必须手动登录。这是一个网站的测试示例,除非登录,否则不允许用户访问根路径。您可以在支持文件中创建一种手动登录用户的方法,然后在您要登录时调用它该用户不需要在每次需要登录用户时使用此代码。

  require' test_helper'

class UserFlowsTest< ActionDispatch :: IntegrationTest
test登录用户被重定向到root_pathdo
get user_session_path
assert_equal 200,status
@david = User.create(email:david @ mail .com,密码:Devise :: Encryptor.digest(User,helloworld))
post user_session_path,'user [email]'=> @ david.email,'user [password]'=> @ david.password
follow_redirect!
assert_equal 200,状态
assert_equal/,路径
end

测试访问主页时,用户被重定向到登录页面do
获得/
assert_equal 302,状态
follow_redirect!
assert_equal/ users / sign_in,路径
assert_equal 200,状态
end
end

编辑:以防万一有助于将来。您可以使用 Warden Test Helpers 进行集成测试,但上述方法是更好的测试。这是一个工作示例:

  require'test_helper'
include Warden :: Test :: Helpers
UserFlowTest类ActionDispatch :: IntegrationTest
test用户可以在登录后看到主页do
@david = User.create(email:david@mail.com,密码:Devise :: Encryptor.digest ,helloworld))
login_as(@david)
get/
assert_equal 200,状态#用户获取root_path,因为他在
assert_equal/,$
logout
get/
assert_equal 302,状态#用户被重定向,因为他已经出来
Warden.test_reset! #reset监狱长每个例子
结束
结束


I'm trying to ensure proper user access is maintained with Devise in Rails 4, and I'm having a hard time logging a user in in the test suite.

The simplest case:

require 'test_helper'
  include Devise::TestHelpers

class SiteLayoutTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:test1)
  end

  test "logged in should get index" do
    sign_in @user
    get users_path
    assert_response :success
    assert_select "title", "User Index"
  end
end

So far I've not done more really than just implement Devise and a Users controller with the appropriate actions.

I consistently get: NoMethodError: undefined method 'env' for nil:NilClass, referring specifically to the line containing sign_in @user and I can find other instances of people getting the same error, but never seem to find an actual solution to the problem I'm attempting to solve.

How do I log a user in with Devise in Rails 4 for testing purposes? Thanks.

EDIT:

fixtures/users.yml

test1:
  id: '1'
  email: 'test1@example.com'
  encrypted_password: <%= Devise::Encryptor.digest(User, "password") %>
  created_at: <%= Time.now - 6.minutes %>
  updated_at: <%= Time.now - 4.minutes %>

SOLUTION IN SITU:

test "logged in should get index" do
  post user_session_path, 'user[email]' => @user.email, 'user[password]' =>  'password'
  get users_path
  assert_response :success
  assert_select "title", "User Index"
end

解决方案

This is from their docs:

"Do not use Devise::TestHelpers in integration tests."

You have to sign in manually. This is an example of a test for a website that does not allow users to get to the root path unless signed in. You can create a method in a support file that signs in the user manually and then call it whenever you want to sign in the user, so that you don't have to use this code every time you need to sign in a user.

require 'test_helper'

 class UserFlowsTest < ActionDispatch::IntegrationTest
   test "signed in user is redirected to root_path" do
     get user_session_path
     assert_equal 200, status
     @david = User.create(email: "david@mail.com", password: Devise::Encryptor.digest(User, "helloworld"))
     post user_session_path, 'user[email]' => @david.email, 'user[password]' =>  @david.password
     follow_redirect!
     assert_equal 200, status
     assert_equal "/", path
   end

   test "user is redirected to sign in page when visiting home page" do
     get "/"
     assert_equal 302, status
     follow_redirect!
     assert_equal "/users/sign_in", path
     assert_equal 200, status
   end
 end

EDIT: Just in case it's helpful in the future. You can use Warden Test Helpers for integration tests but the way above is a better test. This is a working example:

require 'test_helper'
include Warden::Test::Helpers
class UserFlowsTest < ActionDispatch::IntegrationTest
  test "user can see home page after login" do
    @david = User.create(email: "david@mail.com", password: Devise::Encryptor.digest(User, "helloworld"))
    login_as(@david)
    get "/"
    assert_equal 200, status # User gets root_path because he loged in
    assert_equal "/", path
    logout
    get "/"
    assert_equal 302, status # User is redirected because he loged out
    Warden.test_reset! #reset Warden after each example
  end
end

这篇关于如何在Rails4测试中使用Devise登录/注销用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆