Ruby on rails 用rspec测试控制器身份验证的实用方法
我想知道是否有比我现在做的更好的方法来编写控制器请求规范。我正在使用Desive gem进行身份验证。以下是我测试管理员控制器的方法:Ruby on rails 用rspec测试控制器身份验证的实用方法,ruby-on-rails,rspec,devise,Ruby On Rails,Rspec,Devise,我想知道是否有比我现在做的更好的方法来编写控制器请求规范。我正在使用Desive gem进行身份验证。以下是我测试管理员控制器的方法: describe "#index" do context "when not logged in" do it "redirects to root page" do get admin_index_path expect(response).to redirect_to root_path
describe "#index" do
context "when not logged in" do
it "redirects to root page" do
get admin_index_path
expect(response).to redirect_to root_path
end
end
context "when logged in as an user" do
before { sign_in user }
it "redirects to root page" do
get admin_index_path
expect(response).to redirect_to root_path
end
end
context "when logged in as an admin" do
before { sign_in admin }
it "opens the page" do
get admin_index_path
expect(response).to be_success
end
end
end
正如您所看到的,有一些“样板”代码在我的许多控制器上重复。对于需要用户登录的控制器,我必须为每个控制器操作编写一个“未登录”规范。你是怎么做到的?有没有办法缩短/共享规范之间的代码?唯一改变的是路径。好的,我想出了这个解决方案。如果你有更好的主意,请告诉我
shared_examples "requires user login" do |path|
context "when not logged in" do
it "redirects to root path" do
get public_send(path)
expect(response).to redirect_to root_path
end
end
context "as an user" do
it "redirects to root path" do
sign_in create(:user)
get public_send(path)
expect(response).to redirect_to root_path
end
end
end
shared_examples "requires admin login" do |path|
context "as an user" do
it "redirects to root path" do
sign_in create(:user)
get public_send(path)
expect(response).to redirect_to root_path
end
end
context "as an admin" do
it "gets 200" do
sign_in create(:admin)
get public_send(path)
expect(response).to be_success
end
end
end
要使用它们:
it_behaves_like "requires user login", "admin_index_path"
或
好的,我想出了这个解决方案。如果你有更好的主意,请告诉我
shared_examples "requires user login" do |path|
context "when not logged in" do
it "redirects to root path" do
get public_send(path)
expect(response).to redirect_to root_path
end
end
context "as an user" do
it "redirects to root path" do
sign_in create(:user)
get public_send(path)
expect(response).to redirect_to root_path
end
end
end
shared_examples "requires admin login" do |path|
context "as an user" do
it "redirects to root path" do
sign_in create(:user)
get public_send(path)
expect(response).to redirect_to root_path
end
end
context "as an admin" do
it "gets 200" do
sign_in create(:admin)
get public_send(path)
expect(response).to be_success
end
end
end
要使用它们:
it_behaves_like "requires user login", "admin_index_path"
或
@Linus这里是您答案的重构版本
shared_examples "requires login" do |path, user_type|
context "when not logged in" do
it "redirects to root path" do
get public_send("#{path}_path")
expect(response).to redirect_to root_path
end
end
context "as an #{user_type}" do
it "redirects to root path" do
sign_in create(user_type)
get public_send("#{path}_path")
expect(response).to redirect_to root_path
end
end
end
像这样使用它
它的行为类似于用户的“需要登录”、“管理索引”、:user
它的行为类似于“需要登录”、“管理员索引”:admin
for admin@Linus这里是您答案的重构版本
shared_examples "requires login" do |path, user_type|
context "when not logged in" do
it "redirects to root path" do
get public_send("#{path}_path")
expect(response).to redirect_to root_path
end
end
context "as an #{user_type}" do
it "redirects to root path" do
sign_in create(user_type)
get public_send("#{path}_path")
expect(response).to redirect_to root_path
end
end
end
像这样使用它
它的行为类似于用户的“需要登录”、“管理索引”、:user
it\u的行为类似于“需要登录”,“admin\u索引”,“admin
for adminReplaceit\u的行为类似于包含示例
为什么一个替代另一个替代it\u的行为类似于包含示例
为什么一个替代另一个好主意将用户类型作为符号传递,就像工厂机器人需要它一样。谢谢如何传递带有对象的路径?示例:edit\u course\u path(course)
edit\u course\u path(course)
返回可以作为参数传递的字符串,如它的行为类似于“需要登录”,“edit\u course\u path(course)”:admin
但我只能在it
块中编写edit\u course\u path(course)
,对吗?我没有完全理解@Linus。你能添加更多细节吗?把用户类型作为符号传递是个好主意,就像工厂机器人需要它一样。谢谢如何传递带有对象的路径?示例:edit\u course\u path(course)
edit\u course\u path(course)
返回可以作为参数传递的字符串,如它的行为类似于“需要登录”,“edit\u course\u path(course)”:admin
但我只能在it
块中编写edit\u course\u path(course)
,对吗?我没有完全理解@Linus。你能补充更多细节吗?