我想知道是否有更好的方法来编写控制器请求规范,而不是我目前的工作方式。我使用devise 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
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
正如你所看到的,有一些"样板"在我的许多控制器上重复的代码。对于需要用户登录的控制器,我必须写一个"没有登录"每个控制器动作的规范。你怎么做到这一点?有没有办法缩短/分享规范之间的代码?唯一改变的是路径。
答案 0 :(得分:4)
@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
并像
一样使用它 用户 it_behaves_like "requires login", "admin_index", :user
it_behaves_like "requires login", "admin_index", :admin
答案 1 :(得分:0)
好的,我想出了这个解决方案。如果您有任何更好的想法,请告诉我。
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"
或
it_behaves_like "requires admin login", "admin_index_path"