2014-10-20 84 views
6

在Rails 4.1.6中,运行使用脚手架生成的测试时出现InvalidAuthenticityToken错误。有什么办法可以禁用特定测试的真实性标记检查吗?脚手架测试失败,ActionController :: InvalidAuthenticityToken

rails g scaffold user name:string email:string password_digest:string 
rake 

输出:

... 

    1) Error: 
UsersControllerTest#test_should_create_user: 
ActionController::InvalidAuthenticityToken: ActionController::InvalidAuthenticityToken 
    test/controllers/users_controller_test.rb:21:in `block (2 levels) in <class:UsersControllerTest>' 
    test/controllers/users_controller_test.rb:20:in `block in <class:UsersControllerTest>' 

... 

这是源代码:

test "should create admin_user" do 
    assert_difference('Admin::User.count') do 
    post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username } 
    end 

    assert_redirected_to admin_user_path(assigns(:admin_user)) 
end 

回答

8

有一些选项:

- >您可以更改检测CSRF无效令牌行为重置会话(就像它在Rails 3中):

application_controller.rb

protect_from_forgery with: :exception 

protect_from_forgery with: :null_session 

- >你可以做到这一点的条件表达式,是这样的:

if Rails.env.test? 
    protect_from_forgery with: :null_session 
else 
    protect_from_forgery with: :exception 
end 

然而,这给了你一点点不同的配置测试和dev/production env。

- >您可以标记手动测试提供真伪:

def set_form_authenticity_token 
    session[:_csrf_token] = SecureRandom.base64(32) 
end 

,特别是测试:

post :create, admin_user: { email: @admin_user.email, password_digest: @admin_user.password_digest, username: @admin_user.username }, authenticity_token: set_form_authenticity_token 

- >您可以编写自己的助手,是这样的:

def set_form_authenticity_token 
    session[:_csrf_token] = SecureRandom.base64(32) 
end 

alias_method :post_without_token, :post 
def post_with_token(symbol, args_hash) 
    args_hash.merge!(authenticity_token: set_form_authenticity_token) 
    post_without_token(symbol, args_hash) 
end 
alias_method :post, :post_with_token 
+0

我无法让'form_authenticity_token'工作,我猜是因为它是一种受保护的方法。我可以直接用'SecureRandom.base64(32)'(这是'form_authenticity_token'的做法)设置'session [:_ csrf_token]'来通过测试,并在post数据中传递和'authenticity_token'参数相同的值。看起来很骇人,但我不知道还有什么要做。感谢回复。 – Schrute 2014-10-20 19:40:13

+1

我已经编辑了我的答案 - 现在它应该可以工作,并且看起来似乎不那么讨厌;) – Esse 2014-10-20 20:20:38

+0

默认args_hash会有帮助 def post_with_token(symbol,args_hash = {})'' – 2015-02-13 23:29:36

相关问题