Techno Fattie

Josh Carroll

In ancient times... at least according to web standards, I wrote a couple of posts about unit testing with declarative security attributes. It turns out that while using declarative security is pretty awesome, it's clear nobody was thinking about people doing TDD :(

Getting around this was easy enough by simply overriding the Principal using the built in GenericPrincipal and GenericIdentity classes. We even refactored the security setup code into the Initialize method for our unit tests. However, we still had to think about security for every test class!

I can tell you right now that that is a big fat suck! I don't want to see any security related code in my unit test because I'm not testing security right now! What I really want is for my test to look like this and just work.

[TestMethod]
public void ShouldGetSuperSecretFromAgent()
{
var agent = new SecretAgent();

//This line will esplode!!!
var secret = agent.GetSuperSecretStuff();

Assert.IsNotNull(secret);
}

Fortunately, we still have one last trick up our sleeve that we can use to solve our problem once and for all. Writing a custom implementation of IPrincipal and IIdentity. This is so braindead simple, that I'm not even going to explain it... just show you the code.


public class StubPrincipal: IPrincipal, IIdentity
{
public StubPrincipal(String name = "TestUser", Boolean isAuthenticated = true, String authenticationType = "Fake")
{
Name = name;
IsAuthenticated = isAuthenticated;
AuthenticationType = authenticationType;
}

//IPrincipal Members
public IIdentity Identity
{
get { return this; }
}

public bool IsInRole(string role)
{
return true;
}

//IIdentity Members
public string AuthenticationType { get; set; }

public bool IsAuthenticated { get; set; }

public string Name { get; set; }
}

This still leaves the business of wiring it all up. Since the whole point of this refactoring was to not have to worry about doing this for every test!

All your base class are belong to us!

The simplest approach I can think of is to create a base class that will wire up your custom StubPrincipal object in the constructor, and then derive all your test classes from it. Again, this is so braindead simple... just look at the code.


public class SecurityEnabledTest
{
protected StubPrincipal Principal = new StubPrincipal();

public SecurityEnabledTest()
{
Thread.CurrentPrincipal = Principal;
}
}

And now our goal above is reached with one tiny modification.


[TestClass]
public class SecretAgentBehavior_UsingBaseClass: SecurityEnabledTest
{
[TestMethod]
[Description("Test relying on base class to set principal")]
public void ShouldGetSuperSecretFromAgent()
{
var agent = new SecretAgent();

//It works... WOOT!
var secret = agent.GetSuperSecretStuff();

Assert.IsNotNull(secret);
}
}

Voila! Now you can go on your merry little way and focus on the actual method behavior instead of the security meta-data.

But Wait! There is even more awesome!

If you are thinking to yourself "Ok, that is great dude, but what if I actually want to test MY FREAKING SECURITY!"

I've got you covered. Here is a slightly more robust Principal object that will give you a lot more control over how it behaves, which should cover any testing scenario you can think of. It allows you to add roles, and has three modes of operation:
  1. Always Return True
  2. Whitelist
    1. This is how a normal principal operates. If the role is in the list, then you get access.
  3. Blacklist
    1. This works opposite to a normal principal. If the role is in the list, then you get denied access. This is useful for when there are multiple roles needed to perform an action (think nested calls), and you want to see how your code behaves when the user doesn't have one of them.
In the end I hope this helps unit testing efforts, and maybe demystifies the Principal/Identity objects a little bit. You can even use these same techniques to write your own custom security Principal for actual production uses. The concepts are identical.

Cheers,
Josh
comments powered by Disqus