在我的rails应用程序中,我有两个用户角色:'student'和'admin'。他们对不同页面拥有不同的访问权限,例如,'admin'可以访问列表用户页面(索引),但'学生'不能访问。这是使用cancancan控制的。如何使用默认测试框架(minitest)在控制器测试中测试cancancan功能
现在我写测试的控制器和,因为我有两个不同的角色,(据我所知)我需要一个行为的两个独立的测试,例如:
test "should get index for admin" do
sign_in(users(:admin))
get "index"
assert_response :success
end
test "should not get index for student" do
sign_in(users(:student))
get "index"
assert_response :unauthorized
end
其中sign_in(*)
是方法用于处理用户登录(会话等)
由于我正在考虑添加更多角色(例如'manager','agent'),因此每次添加角色时都需要为所有控制器方法添加新测试。这是乏味的,而不是“干”,所以我试图找到一个更优雅的方式来处理这个问题。这是我的第一个想法:
在我test_helper.rb中,我说:
def assert_admin_only(&block)
sign_in(users(:admin))
instance_exec(&block)
assert_response :success
sign_out
sign_in(users(:student))
instance_exec(&block)
assert_response :unauthorized
sign_out
sign_in(users(:agent))
instance_exec(&block)
assert_response :unauthorized
sign_out
end
然后在我的测试:
test "should get index for admin only" do
assert_admin_only do
get "index"
end
end
所以,每次我添加了一个新的角色,我只必须在test_helper.rb方法中添加几行以测试这些功能。
但是,它并不像我想的那样工作,因为“功能测试允许您测试每个测试方法的单个控制器操作。”根据Rails API DOC,而在我的代码中,我发射了两个动作甚至更多。出于某种原因,我无法弄清楚,似乎sign_in
和sign_out
实际上并没有改变current_user(尽管它们在真正的请求中完美地工作),这基本上使我的尝试失败。
总而言之,我想重新使用我的测试来处理不同的用户角色,这样我就不必在每次添加新角色时都浪费时间复制和粘贴现有代码。如果你们能提供一些出色的想法,我将非常感激。