我在自己的控制器中覆盖SessionsController,并尝试使用RSpec进行测试。拳头,我用
设置@request.env["devise.mapping"] = Devise.mappings[:user]
我的规格:
require 'rails_helper'
要求' authentication_helper'
RSpec.describe Users :: SessionsController,type :: controller do 包括AuthenticationHelper
描述'创建新会话'做
before(:each) do
setup_auth
end
let(:user) {FactoryGirl.create(:user, username: 'john', email: 'john@gmail.com', password: 'pwd1234')}
it 'should return 200 with valid username and password' do
post :create, user: {login: 'john', password: 'pwd1234'}
expect(response).to have_http_status 200
expect(controller.current_user.id).to eq(user.id)
end
端 端
我的SessionsController只返回http 401或http 200。 当我运行我的规范时,我收到此错误:
NoMethodError:
未定义的方法authenticate?' for nil:NilClass
# /usr/local/bundle/gems/devise-3.5.6/app/controllers/devise_controller.rb:103:in
require_no_authentication'
#./spec/controllers/users/sessions_controller_spec.rb:16:in block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:45:in
阻止(3级)&#39;
#/usr/local/bundle/gems/database_cleaner-1.6.0/lib/database_cleaner/generic/base.rb:16:in cleaning'
# /usr/local/bundle/gems/database_cleaner-1.6.0/lib/database_cleaner/base.rb:98:in
清洁&#39;
#/usr/local/bundle/gems/database_cleaner-1.6.0/lib/database_cleaner/configuration.rb:86:in block (2 levels) in cleaning'
# /usr/local/bundle/gems/database_cleaner-1.6.0/lib/database_cleaner/configuration.rb:87:in
来电&#39;
#/usr/local/bundle/gems/database_cleaner-1.6.0/lib/database_cleaner/configuration.rb:87:in cleaning'
# ./spec/rails_helper.rb:44:in
阻止(2级)&#39;
我做错了什么?
答案 0 :(得分:3)
您知道Devise提供了针对控制器规格的RSpec测试助手。但是,在请求规范中,它们将不起作用。
这是从Devise Wiki改编而成的针对请求规范的解决方案。我们将只使用Warden的测试助手-您可能已经将它们加载到Cucumber测试中。
首先,我们定义sign_in和sign_out方法。这些行为的行为就像您从控制器规格中了解到的那样:
module DeviseRequestSpecHelpers
include Warden::Test::Helpers
def sign_in(resource_or_scope, resource = nil)
resource ||= resource_or_scope
scope = Devise::Mapping.find_scope!(resource_or_scope)
login_as(resource, scope: scope)
end
def sign_out(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
logout(scope)
end
end
最后,加载该模块以获取请求规范:
RSpec.configure do |config|
config.include DeviseRequestSpecHelpers, type: :request
end
完成。您现在可以像这样编写请求规范:
sign_in create(:user, name: 'John Doe')
visit root_path
expect(page).to include('John Doe')
参考:
https://makandracards.com/makandra/37161-rspec-devise-how-to-sign-in-users-in-request-specs
答案 1 :(得分:1)
您必须存根warden.authenticate!
调用,而不仅仅是current_user
方法。
对于登录成功测试用例:
before(:each) do
# assuming `user` is defined and returns a User instance
allow(request.env['warden']).to receive(:authenticate!).and_return(user)
allow(controller).to receive(:current_user).and_return(user)
end
对于失败案例:
before(:each) do
allow(request.env['warden']).to receive(:authenticate!).and_throw(:warden, scope: :user)
allow(controller).to receive(:current_user).and_return(nil)
end
这在设计4.x中对我有效。在https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs
中找到了答案 2 :(得分:0)
您应该有登录帮助,例如
module AuthenticationHelpers
module Controller
def sign_in(user)
controller.stub(:current_user).and_return(user)
controller.stub(:user_id).and_return(user.id)
end
end
module Feature
def sign_in(user, options={})
visit "/users/sign_in"
fill_in "Email", with: user.email
fill_in "Password", with: options[:password]
click_button "Log in"
end
end
end
任何疑虑,请随时发表评论