danpalmer
danpalmer

Reputation: 2173

Testing static classes and methods in C# .NET

I'm relatively new to unit testing, and very new to C#, but I've been trying to test code that uses static classes with static methods, and it seems like I have to write huge amounts of boilerplate code in order to test, and that code would then also probably need to be tested.

For example: I'm using the System.Web.Security.Membership class, with a method ValidateUser on it. It seems like I need to create an interface IMembership containing the method ValidateUser, then create a class MembershipWrapper that implements IMembership, implementing the method ValidateUser and passing the arguments on to the actual Membership class. Then I need to have properties on my class that uses the Membership to reference the wrapper so that I can inject the dependency for a mock object during testing.

So to test 1 line of code that uses Membership, I've had to create an interface, and a class, and add a property and constructor code to my class. This seems wrong, so I must be getting something wrong. How should I be going about this testing? I've had a brief look at some frameworks/libraries that do dependency injection, but they still appear to require lots of boilerplate, or a very deep understanding of what's going on under the hood.

Upvotes: 5

Views: 1696

Answers (4)

Gjeltema
Gjeltema

Reputation: 4156

If you're using VS2012, you can always use Shims in Microsoft Fakes for static calls (or .Net library calls too).

http://msdn.microsoft.com/en-us/library/hh549175(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/hh549176.aspx

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

I don't see anything wrong in making your system loosely coupled. I believe you don't complain on creating constructor parameters and passing abstract dependencies to your classes. But instantiating dependencies in place looks so much easier, does it?

Also, as I pointed in comments, you can reuse wrappers later. So, that is not such useless work, as it seems from first glance.

Upvotes: 3

dave clements
dave clements

Reputation: 1505

I you're not happy taking the approach of constructor injection, you could look at using Ambient Context

You basically set up a default which will call System.Web.Security.Membership.ValidateUser

You then call the exposed method on the context in your code and you can now mock it for your tests

This allows you to write less setup code, but it also hides the fact that you have a dependency, which might be a problem in the future (depending on how you're reusing code)

Upvotes: 0

sll
sll

Reputation: 62484

You are on the right way, and think you are not testing single line of code, in this case you are writing important test to ensure that your code interacts with membership provider in the right way, this is not simple unit test rather "mock-based" integration test. I think it worth creating all these mocks and have covered by tests this part of application.

And yes, it seems overkill but no other way - either you use some helpers/libraries either wrap third-party static dependencies yourself.

Upvotes: 3

Related Questions