我正在使用.NET 3.5和Nunit 2.5.10。我正在尝试编写一些测试来通过PrincipalPermissionAttribute
在类级别验证基于角色的安全实施。测试似乎成功(它得到一个绿色的复选标记)并且Assert.Throws
调用正确捕获异常,并且关于异常的所有其他断言都通过了。但是,一旦TearDown在测试运行后完成,NUnit将重新抛出异常。因此,即使测试“通过”,每个测试都会显示异常是在执行测试运行时抛出未处理的异常。
我猜我做错了什么,但无法搞清楚。我的测试是:
Public Sub New_TheForm_NoRoles_DeniesAccess()
' attempt to create a new instance of the form, but it should throw an exception with an inner SecurityException
Dim ex As TypeInitializationException = Assert.Throws(Of TypeInitializationException)( _Function() New TheForm(), "Only admins and editors should have access.")
Assert.That(ex.InnerException, [Is].TypeOf(GetType(SecurityException)), "Initialization should fail because of a SecurityException.")
End Sub
表单在类级别具有PrincipalPermission属性,如下所示:
<PrincipalPermission(SecurityAction.Demand, Role:=Security.Roles.ADMINISTRATORS)> _
<PrincipalPermission(SecurityAction.Demand, Role:=Security.Roles.EDITORS)> _
Public Class TheForm
' ... more class code here ...
End Class
除了其他检查甚至不向用户提供选项之外,我们还试图根据收到的角色拒绝访问给定表单。角色常量与域安全组相关联,我知道它们有效(它们在应用程序运行时正确地允许/拒绝)。
在应用程序的早期,我们 通过调用UserSecurity.Initialize(Nothing)
来初始化我们的主要策略。单例UserSecurity的Initialize方法在这里:
Public Shared Sub Initialize(ByRef principalToUse As IPrincipal)
' if we don't have a principal, then use the windows principal
If (principalToUse Is Nothing) Then
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
' otherwise, use the principal passed in
Else
Thread.CurrentPrincipal = principalToUse
End If
End Sub
基本上,通常使用Nothing
在应用程序中调用Initialize,以便我们使用Windows Principal。在单元测试期间,我们使用没有角色的GenericPrincipal初始化它,以便我们可以测试是否抛出了SecurityException。
测试正在通过,但NUnit似乎正在重新抛出拆解后的异常。我可能做错了什么想法?
答案 0 :(得分:1)
您的表单是否可以最终化,或者您是否可以在测试中设置“允许”主体的上下文之外处理表单实例(例如,通过using语句)?在任何一种情况下,您最终都会尝试在不允许在表单中运行任何方法的用户帐户下运行方法(终结器或Dispose)。有关更多详细信息和解决方法,请参阅http://msmvps.com/blogs/calinoiu/archive/2006/01/07/why-is-my-application-coughing-up-a-securityexception-after-my-code-stops-running.aspx。
答案 1 :(得分:0)
正如Nicole Calinoiu回答的那样,这是由于稍后调用Dispose,在测试运行后导致的,导致SecurityException。来自NUnit的错误具有误导性,称它是“在测试期间”。
这里为后人发布的解决方法是确保正确清理测试夹具的TearDown
中的主体。在这种情况下,它意味着确保将Thread.CurrentPrincipal
重置为具有适当权限的内容,以便NUnit可以处理事情,即使在测试之后也是如此。