Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
There has been mixed reaction to the removal of [SetUp]
and [TearDown]
in xUnit.net. Personally, I think it's great as it helps to raise unit test 'smells', particularly around how classes interact with each another. Here's a small example of how we can use the BeforeAfterTestAttribute
in xUnit to remove duplicate code. (It's based on the security workaround I talked about yesterday.)
Instead of repeating three lines of code in each unit test to update the current identity, we can just define an attribute like [AssumeIdentity]
that will take care of things for us. Here's the little fixture I wrote to test it.
public class AssumeIdentityAttributeFixture
{
[Test]
public void CallingSecuredMethodWillThrow()
{
Assert.Throws<SecurityException>(delegate
{
SecuredMethod();
});
}
[Test, AssumeIdentity("Munchkin")]
public void CallingSecuredMethodWithAssumedIdentityPasses()
{
Assert.DoesNotThrow(delegate
{
SecuredMethod();
});
}
[PrincipalPermission(SecurityAction.Demand, Role = "Munchkin")]
public void SecuredMethod() {}
}
public class AssumeIdentityAttribute : BeforeAfterTestAttribute
{
public AssumeIdentityAttribute(string name)
{
this.name = name;
}
public override void Before(MethodInfo methodUnderTest)
{
originalPrincipal = Thread.CurrentPrincipal;
GenericIdentity identity = new GenericIdentity("boo");
GenericPrincipal principal =
new GenericPrincipal(identity, new string[] { name });
Thread.CurrentPrincipal = principal;
}
public override void After(MethodInfo methodUnderTest)
{
Thread.CurrentPrincipal = originalPrincipal;
}
readonly string name;
IPrincipal originalPrincipal;
}
As you can see, before each test it executed, we update the current thread's identity, and then reset it after the test has run. It doesn't get much simpler than that :)