如何测试 after_sign_in_path_for(resource)?
我在 Rails 应用程序上设置了身份验证和注册。我使用 after_sign_in_path_for()
根据各种场景自定义用户登录时的重定向。
我想问的是如何测试这个方法?似乎很难隔离,因为它是在用户登录时由 Devise 自动调用的。我想做这样的事情:
describe ApplicationController do
describe "after_sign_in_path_for" do
before :each do
@user = Factory :user
@listing = Factory :listing
sign_in @user
end
describe "with listing_id on the session" do
before :each do
session[:listing_id] = @listing.id
end
describe "and a user in one team" do
it "should save the listing from the session" do
expect {
ApplicationController.new.after_sign_in_path_for(@user)
}.to change(ListingStore, :count).by(1)
end
it "should return the path to the users team page" do
ApplicationController.new.after_sign_in_path_for(@user).should eq team_path(@user.team)
end
end
end
end
end
但这显然不是这样做的方法,因为我只是得到一个错误:
Failure/Error: ApplicationController.new.after_sign_in_path_for(@user)
RuntimeError:
ActionController::Metal#session delegated to @_request.session, but @_request is nil: #<ApplicationController:0x00000104581c68 @_routes=nil, @_action_has_layout=true, @_view_context_class=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>
那么,我该如何测试这个方法?
I have devise authentication and registration set up on my Rails app. I'm using after_sign_in_path_for()
to customise the redirect when the user signs in based on various scenarios.
What I'm asking is how to test this method? It seems hard to isolate since it is called automatically by Devise when the user signes in. I want to do something like this:
describe ApplicationController do
describe "after_sign_in_path_for" do
before :each do
@user = Factory :user
@listing = Factory :listing
sign_in @user
end
describe "with listing_id on the session" do
before :each do
session[:listing_id] = @listing.id
end
describe "and a user in one team" do
it "should save the listing from the session" do
expect {
ApplicationController.new.after_sign_in_path_for(@user)
}.to change(ListingStore, :count).by(1)
end
it "should return the path to the users team page" do
ApplicationController.new.after_sign_in_path_for(@user).should eq team_path(@user.team)
end
end
end
end
end
but that's obviously not the way to do it because I just get an error:
Failure/Error: ApplicationController.new.after_sign_in_path_for(@user)
RuntimeError:
ActionController::Metal#session delegated to @_request.session, but @_request is nil: #<ApplicationController:0x00000104581c68 @_routes=nil, @_action_has_layout=true, @_view_context_class=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>
So, how can I test this method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
奇怪的是,我今天就想知道这件事。这就是我的想法。我创建了 ApplicationController 的匿名子类。在这个匿名子类中,我将要测试的受保护方法公开为公共方法。然后我直接测试了它们。
Oddly, I was wondering this very thing today. Here's what I came up with. I created an anonymous subclass of ApplicationController. In this anonymous subclass, I exposed the protected methods that I wanted to test as public methods. Then I tested them directly.
类似地,如果您想在注册后测试重定向,您有两个选择。
首先,您可以遵循与上面类似的模式,并非常直接地测试 RegistrationsController 中的方法:
或者,您可以采取更多集成测试的方法并执行以下操作:
On a similar note - if you want to test the redirect after sign-up, you have two options.
First, you can follow a pattern similar to above and very directly test the method in RegistrationsController:
Or, you can take a more integration-testing sort of approach and do the following:
我最近通过谷歌找到了这个答案,并认为我会添加我的解决方案。我不喜欢接受的答案,因为它正在测试应用程序控制器上方法的返回值,而不是测试应用程序的所需行为。
我最终只是测试了创建新会话作为请求规范的调用。
(Rails 5、Devise 4、RSpec 3)
I found this answer through Google recently and thought I would add my solution. I didn't like the accepted answer because it was testing the return value of a method on the application controller vs testing the desired behavior of the app.
I ended up just testing the call to create a new sessions as a request spec.
(Rails 5, Devise 4, RSpec 3)
对于新人,我建议这样做:
For the newcomers, I would recommend doing this way: