问题描述
我能够使用 Devise 的 sign_in
方法在我的控制器规范中登录用户.但是现在我要从我的应用程序中删除 Devise,我不太确定如何单独使用 Warden 来获得类似的功能.
我应该如何设置 spec/spec_helper.rb
和相关的 spec/support/*.rb
文件,以使 Warden 在控制器规格内充分运行?>
我已经尝试在 spec/support/warden.rb
设置一个文件,其中包含以下内容:
RSpec.configure 做 |config|config.include Warden::Test::Helpers配置后做Warden.test_reset!结尾结尾
然后我有 before
类似的调用来验证 user
工厂:
before { login_as FactoryGirl.create(:user) }
但这是我一直看到的错误:
名称错误:未定义的方法 `user' 为 nil:NilClass
此错误可追溯到我在控制器中的 authenticate_user!
方法:
def authentication_user!redirect_to login_path,注意:您需要先登录或注册才能继续."如果 env['warden'].user.nil?结尾
如果有人能提供任何指导,我将不胜感激.
您尝试执行的操作存在基本问题.Warden 是一个 Rack 中间件,但 RSpec 控制器规范甚至不包括 Rack,因为这些类型的规范并不意味着运行您的完整应用程序堆栈,而只是您的控制器代码.您可以使用单独的测试来测试您的中间件,但在这种情况下,我认为测试 Warden 本身是否有效没有意义.
要测试您是否正确配置了 Warden,您应该使用请求规范或集成规范(cucumber、capybara 或类似规范).
虽然在控制器规范中模拟 Warden 在技术上是可能的,但我认为它并没有为您提供太多好处,同时显着增加了测试代码的复杂性.请记住,Rack 中间件旨在以透明的方式运行,以便您可以轻松地根据需要交换中间件.你的控制器根本不应该直接依赖 Warden(也许除了 ApplicationController
),实际上,所以你的控制器对 Warden 的测试依赖是破坏封装的标志.
我最近遇到了同样的问题,所以我希望这篇评论有用.
I was able to use Devise's sign_in
method to log in a user in my controller specs. But now that I'm removing Devise from my application, I'm not quite sure how to get similar functionality working with just Warden on its own.
How should I go about setting up spec/spec_helper.rb
and related spec/support/*.rb
files to get Warden running within controller specs sufficiently?
I've tried setting up a file at spec/support/warden.rb
with these contents:
RSpec.configure do |config|
config.include Warden::Test::Helpers
config.after do
Warden.test_reset!
end
end
Then I have before
calls similar to this to authenticate a user
factory:
before { login_as FactoryGirl.create(:user) }
But here is the error that I keep seeing:
NameError:
undefined method `user' for nil:NilClass
This error traces back to my authenticate_user!
method in the controller:
def authenticate_user!
redirect_to login_path, notice: "You need to sign in or sign up before continuing." if env['warden'].user.nil?
end
I'd appreciate any guidance that anyone could provide.
There is a basic problem with what you are trying to do. Warden is a Rack middleware, but RSpec controller specs don't even include Rack, as these types of specs are not meant to run your full application stack, but only your controller code. You can test your middleware with separate tests just for those, but in this case, I don't think it makes sense to test that Warden itself works.
To test that you have Warden configured correctly, you should use request specs or integration specs (cucumber, capybara or similar).
Although it is technically possible to mock out Warden in controller specs, I think it is not providing you much benefit while increasing the complexity of your test code significantly. Keep in mind that Rack middleware is meant to operate in a transparent way so that it is easy to swap middleware in and out as you like. Your controller should not be directly dependent on Warden at all (except perhaps for ApplicationController
), actually, so having a test dependency on Warden for your controller is a sign of broken encapsulation.
I ran into this same issue recently so I hope this comment will be useful.
这篇关于配置 Warden 以在 RSpec 控制器规范中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!