2012-03-01 72 views
0

我正在使用.NET 3.5和Nunit 2.5.10。我试图编写一些测试来验证我们在课程级别通过PrincipalPermissionAttribute执行的基于角色的安全性实施。测试似乎成功了(它得到一个绿色复选标记)并且Assert.Throws调用正确捕获异常,并且所有其他有关异常的断言都会通过。但是,一旦测试运行后TearDown完成,NUnit就会重新抛出异常。因此,即使测试“通过”,每个测试都显示异常是在执行测试运行时抛出未处理的异常。用于测试类级PrincipalPermissionAttribute需求的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的初始化方法是在这里:

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让我们使用Windows校长。在单元测试期间,我们用一个没有角色的GenericPrincipal对它进行初始化,以便我们可以测试SecurityException被抛出。

测试正在通过,但NUnit似乎在重新抛出Teardown后的异常。任何想法我可能做错了什么?

回答

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

+0

我确实找到了答案,然后回来看到你的。你是对的 - 具体来说,这个问题是因为Dispose被调用,而被拒绝。我会给你答案,并在另一个详细的解决方法。 – Sean 2012-03-02 18:02:27

0

正如Nicole Calinoiu所回答的那样,这是由于在测试运行后稍后调用Dispose,,导致SecurityException。 NUnit的错误是误导性的,说它是'在测试期间'。

解决方法,这里张贴的后代,是为了确保妥善清理TearDown的委托人为测试夹具。在这种情况下,这意味着确保将Thread.CurrentPrincipal重置为具有适当权限的内容,以便NUnit可以处理事情,即使在测试之后。