[英]Test User Authentication with RSpec
I work with simple rails 4.1.0
app and do not use devise. 我使用简单的rails
4.1.0
应用程序,不使用设计。 I'm testing application controller: 我正在测试应用程序控制器:
class ApplicationController < ActionController::Base
protected
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def signed_in?
!!current_user
end
helper_method :current_user, :signed_in?
def current_user=(user)
@current_user = user
session[:user_id] = user.try :id
end
# want to test this method
def authenticate_user!
render nothing: true, status: :unauthorized unless current_user
end
end
I have a problem with authenticate_user!
我有
authenticate_user!
的问题authenticate_user!
method. 方法。 Full spec see here .
完整规格见这里 。 Method Spec:
方法规格:
describe 'authenticate_user!' do
context 'when user logged in' do
before { subject.send(:current_user=, create(:user)) }
it 'do nothing' do
expect(subject.send(:authenticate_user!)).to eq nil
end
end
context 'when user not logged in' do
controller do
before_action :authenticate_user!
def custom
render :text => 'response'
end
end
before do
subject.send(:current_user=, nil)
routes.draw { get 'custom' => 'anonymous#custom' }
get :custom
end
it 'returns unauthorized status' do
expect(response).to be_nil
end
# before do
# subject.send(:current_user=, nil)
# subject.send(:authenticate_user!)
# end
#
# it { render status: :unauthorized }
# it 'renders nothing' do
# expect(response).to be_nil
# end
end
end
It works when user logged in, but when there is no one I tried 2 methods: anonymous controller and simply tried to call this method (commented here). 它在用户登录时有效,但是当没有人时,我尝试了2种方法:匿名控制器,只是尝试调用此方法(在此处注释)。 Also i tried to inherit
TestApplicationController
from ApplicationController
and the result the same as with anonymous controller. 此外,我试图从
ApplicationController
继承TestApplicationController
,结果与匿名控制器相同。 So in this case error is next: 所以在这种情况下错误是下一个:
Failure/Error: expect(response).to be_nil
expected: nil
got: #<ActionController::TestResponse:0x007fc03b158580 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fc03b0e3938>, @stream=#<ActionDispatch::Response::Buffer:0x007fc03b08bc10 @response=#<ActionController::TestResponse:0x007fc03b158580 ...>, @buf=[" "], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", ....
So it returns some response despite that current_user
set to nil and there is before_action :authenticate_user!
所以它返回一些响应,尽管
current_user
设置为nil并且有before_action :authenticate_user!
in controller. 在控制器中。 I guess it ignores it.
我猜它忽略了它。
In case of 的情况下
before do
subject.send(:current_user=, nil)
subject.send(:authenticate_user!)
end
it { render status: :unauthorized }
it 'renders nothing' do
expect(response).to be_nil
end
Error is next: 错误是下一个:
Failure/Error: subject.send(:authenticate_user!)
Module::DelegationError:
ActionController::RackDelegation#status= delegated to @_response.status=, but @_response is nil: #<ApplicationController:0x007fe854c592b8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=#<ActionController::TestRequest:0x007fe854c78c80 @env={"rack.version"=>[1, 2], "rack.input"=>#<StringIO:0x007fe8544fbf98>, "rack.errors"=>#<StringIO:0x007fe8544f0080>, "rack.multithread"=>true, "rack.multiprocess"=>true, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "SERVER_NAME"=>"example.org", "SERVER_PORT"=>"80",
It has no response object to set status. 它没有设置状态的响应对象。
Also, in this case: 此外,在这种情况下:
controller do
# before_action :authenticate_user!
def custom
authenticate_user!
render :text => 'response'
end
end
The error is different: 错误是不同的:
Failure/Error: render :text => 'response'
AbstractController::DoubleRenderError:
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
So, render works, but 2 times, and it throws an error. 因此,渲染工作,但2次,它会引发错误。
I found a lot of variety similar tests, but mostly it was devise and methods which i perform. 我发现了很多种类似的测试,但主要是我设计的设计和方法。
Thanks for help. 感谢帮助。
Figured out. 想通了。 The point is - response should not be nil since action answers something (renders and not nil - empty string).
关键是 - 响应不应为零,因为动作回答了一些事情(渲染而不是空 - 空字符串)。 And
render status: :unauthorized
wrong too, there is no render in spec, it's a line from controller (i wonder how it appears there). render status: :unauthorized
错误,规范中没有渲染,它是来自控制器的一条线(我想知道它是如何出现的)。 So the right spec for this method: 所以这个方法的正确规范:
context "when user not logged in" do
controller(ApplicationController) do
before_action :authenticate_user!
def custom
render text: 'response'
end
end
before do
subject.send(:current_user=, nil)
routes.draw { get 'custom' => 'anonymous#custom' }
get 'custom'
end
it { should respond_with :unauthorized }
it "returns nothing" do
expect(response.body).to be_blank
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.