所以,我正在乱用我的应用程序测试用户权限,但这个测试真的很奇怪。 这是我试图在ContentsController中工作的前过滤器:
before_filter :only => :destroy do |controller|
controller.prevent_packet_sniffing_destroy_hack(controller_name.classify.constantize)
end
我正在努力让这个控制器的一组测试工作,以便我可以将之前的过滤器复制到具有类似行为的其他控制器
测试:
should "not allow the deleting of #{plural_name} on different accounts" do
login_as(@user)
p = Factory(factory_name, :account => Factory(:account))
assert_difference("#{klass}.count", 0) do
delete :destroy, :id => p.id
klass.find_by_id(p.id).should_not be_nil
end
end
对于那些感兴趣的人,这是一个广义的测试,我在具有类似功能的所有对象上运行。 以下是方法参数'klass'
定义的变量 factory_name = klass.name.tableize.singularize.to_sym
plural_name = klass.name.tableize
singular_name = klass.name.tableize.singularize
我试图测试的控制器的destroy方法:
def destroy
@content = Content.find(params[:id])
if not has_permission_to_change?(@content)
flash[:error] = 'You do not have permission to delete this content.'
else
@content.destroy
end
respond_to do |format|
format.html { redirect_to(contents_url) }
end
end
执行权限测试的两种方法:
def prevent_packet_sniffing_destroy_hack(klass)
if not has_permission_to_change?(klass.find(params[:id]))
puts "should be denying access"
# render :template => "/error/401.html.erb", :status => 401
return false
end
end
def has_permission_to_change?(object)
if (current_user.is_standard? and object.user_id != current_user.id) or
object.account_id != current_account.id
return false
else
return true
end
end
最后,控制台输出
Loaded suite test/functional/contents_controller_test
Started
...should be denying access
E........
Finished in 1.068664 seconds.
1) Error:
test: destroy contents! should not allow the deleting of contents on different accounts. (ContentsControllerTest):
RuntimeError: This content should not be allowed to be deleted
你会注意到,在测试过程中,失败的那个打印“应该拒绝访问”,就像我之前的过滤器中的puts一样。
我还在flash错误的上方放置了一个puts语句,其中显示“您没有权限删除此内容”并且会打印出来。
*注意:当使用Web浏览器和数据包拦截器进行实际测试时,该功能在开发模式下正常工作。
非常感谢任何帮助。
答案 0 :(得分:0)
重新阅读你的测试:
begin
delete :destroy, :id => p.id
raise "This #{singular_name} should not be allowed to be deleted"
rescue ActiveRecord::RecordNotFound
assert true
end
您正在检查的是destroy
行动是否顺利进行。情况总是如此(除非你通过Content
没有id
,但它怎么会发生?)。
您实际上不会测试对象是否被销毁。
你应该这样重写:
should "not allow the deleting of #{plural_name} on different accounts" do
login_as(@user)
p = Factory(factory_name, :account => Factory(:account))
delete :destroy, :id => p.id
klass.name.find_by_id(p.id).should be_nil
end
请注意,您在此处缺少单元测试,您应该使用存根稍微隔离用例。