Weaving with xUnit.net


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 🙂

Skip to main content