【发布时间】:2015-12-27 21:20:47
【问题描述】:
在我的 Rails 应用程序中,我有两个用户角色:“学生”和“管理员”。他们对不同页面有不同的访问权限,例如,“admin”可以访问列表用户页面(索引),但“student”不能。这是使用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(*) 是处理用户登录(会话等)的方法
由于我正在考虑添加更多角色(例如“经理”、“代理”),因此每次添加角色时都需要为所有控制器方法添加新测试。这很乏味而不是“干”,所以我试图找到一种更优雅的方式来处理这个问题。这是我的第一个想法:
在我的 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 (尽管它们在实际请求中工作得很好),这基本上使我的尝试失败了。
总之,我想为不同的用户角色重复使用我的测试,这样我就不必在每次添加新角色时都浪费时间复制和粘贴现有代码。如果你们能提供一些绝妙的想法,我将不胜感激。
【问题讨论】:
标签: ruby-on-rails unit-testing minitest cancancan