Kent Boogart just released his first drop on an implementation for CAB and WPF. As cool as that is, that’s not what this post is about.

This is my first time reading Kent’s blog, and he brings up an interesting topic: Unit Testing in .Net. He shines the light on some troubling areas regarding unit testing in the .Net framework, and offers up a wish for a potential solution. I’ve had the same concerns he’s voiced, but in recent weeks certain tools have come across my desk that have helped me solve these problems.

First, Kent talks about unit testing internal methods:

Inevitably I’ve found the need to expose internal members for testing purposes only.

Anyone who’s been around this Unit Testing circle for a little while knows there’s been a huge debate about whether to unit test private/protected/internal methods or not. Protected members are easy enough to unit test – just subclass the class under test and expose the method you want to test. But private & internal methods are a bit tougher. Part of the debate isn’t just “should you” test private methods, but “how can you test” private methods.

Well, there’s a solution, and it turns out it’s pretty elegent. Tim Stall has written an article over at CodeProject that shows just how you can unit test private methods without any alteration to your production code at all. With a slick use of Reflection, you can unit test private methods until your heart is content. It also works for internal methods.

I simply took Tim’s methods and wrapped them in a class I call TestClass, and then all subsequent NUnit test fixture classes inherit from it. At any time, if I want to test a private or internal method in the class under test, I just need to make a call to the RunInstanceMethod or RunStaticMethod in the base test fixture class, passing along the proper type, method name and parameters. Very slick, very easy. Sample code:


// In class MyObject...
private string GetMyName(string first, string last)
{
return first + " " + last;
}


[Test]
public void Test()
{
MyObject myObject = new MyObject();
object obj = RunInstanceMethod(typeof (MyObject), "GetMyName", myObject, "Chris", "Holmes");
Assert.AreEqual("Chris Holmes", obj);
}

Now for a personal commentary on this approach: I’ve long wanted to be able to unit test private methods directly. I felt like ultimately it would (a) make the code writing process easier and (b) give me more confidence in the code. However, after actually doing it with the Reflection method, I find myself torn between this way and the “test private methods through the public interface” camp.

I’ll explain.

The reason I don’t like testing private methods is twofold. First, I really am only interested in the public API and whether it works or not. I don’t care how my private methods manipulate their variables or data, only that they arrive at the correct results, and I can test that through the public interface. Now, the downside to that is the intagibles that testing brings to an application: confidence that the code has been exercised/tested and works. That said, with a code coverage tool like NCover I can achieve that confidence. It allows me to see the lines of code being tested, and that lets me know if I’m not reaching any code (and thus I need to write additional tests to reach those lines). In fact, I rather like the code coverage tool because I find it aids me in writing test cases against the public API to ensure I’m exercising the private methods.

However, I can see a benefit to testing private methods directly, and it is this: decoupled methods. I don’t see a lot written on this topic but I think it’s important. Inside a class you can end up with a lot of private methods manipulating member variables without having them passed as parameters. This leads to high method coupling, something that seems like a “code smell” to me.

When you’re testing through the public API and only the public API, you can write some very highly coupled private methods. You’ve probably seen classes like this; you may have even written a few (I know I’ve written my fair share). Assuming you think that’s a bad thing (and I sort of do) then being able to test those private methods directly will steer you toward loosly coupled private methods that take explicit parameters and provide explicit return values. So, in that sense, I really like the idea of testing privite methods.

Bottom line: At least now there’s an answer to testing private methods. With Reflection, you can unit test private methods until your heart is content. Whether you want to do that or not is now truly a philosophical debate. At least the “how” part has been answered :)

This subject somewhat leads into the next thing that Kent laments about, which is code coverage:

What’s more, no combination of frameworks and techniques I’ve found allows you to perform close to 100% code coverage without hacking your code base.

Well, with the Reflection capability, I think it’s now possible to get there without hacking your code base. But maybe more importantly, I think you can get 100% code coverage simply by unit testing through the public interface, and utilizing a variety of custom mock objects to reach all possible cases (more on mocks further down). The big issue here, as I see it, is: do I have a test case to exercise these particular lines of code, and if I don’t, then why not? Most often this seems to me to be related to not having a mock object in a state that will actually cause those lines of code to execute, and thus test if they work.

Another point Kent raises is this:

In other cases I’ve found mock libraries limited in what they can mock because of the fact that they typically generate a separate assembly at runtime.

Like Kent, I’ve tried most mock frameworks. After working with them, I’ve decided on the following: Mock frameworks stink. It’s not that they’re bad, faulty or don’t work – they do exactly what the authors describe and that’s theoretically a great thing in this bold new world of automated testing. But the reason why I think they stink is because of the setup involved with making a single mock object work. It just takes too darn much code to setup a mock object under test with all the expected results, and even then you’re really limited in the information you can get out of the mock object, because it’s going to match the signature of whatever it is mocking.

Why not just use the real object with a bunch of dummy data? Better yet, let’s use the real object and add to it, providing properties that give us information on changes made to the state of the data. We can track method calls, state changes, anything our heart desires, and with little effort. I see this approach used a lot when people are testing views in an MVP/MVC scenario, where they will implement a quick boolean flag to ensure some aspect of the view is properly called at a certain point in time, or expose a public property so they can check data that is passed. But when it comes to testing other objects in their application they seem to turn to a mock framework instead, which through my experience has been more complicated.

And so what we’ve started doing is mocking our own objects, and not relying on a dynamic mock framework to provide us our mocks. Our application, like many real world business applications, is very data centric. Lots of domain objects and services being used by the parts of our application that we would like to test. Instead of mocking these things with a mock framework and setting up every expected result in tedious fashion, we just build the actual mock objects ourselves in a testing library using the interfaces, abstractions and classes we’ve written. It doesn’t eliminate the tedium of setting those objects up, but it does give us the power to do more with those mock objects.

Since we have 100% control of the “mock” objects we’re implementing, we have access to the internal guts of the things; we can expose additional properties and methods that allow us to check and ensure state changes happen when they’re supposed to happen, at the moment they’re suppose to happen. We can, in essence, create the real object with additional capabilities that make it more valuable as a testing tool. It’s like adding the utility belt to Batman.

To me, that’s where the real power lies in a mock object. Being able to snatch the data and examine it at various points along the way; it lets me know my code is doing the right thing.

And the cool thing is, creating these objects takes hardly any more time than working with a mock object framework and setting up expecations. Since we’ve written the objects to begin with (or are using 3rd party objects we’re familiar with) then there’s no confusion over what we expect the object to do, or contain. Design patterns can aid us too; we can quickly churn out several different flavors of an object with a factory pattern, then utilize these flavors with a couple lines of code in our test fixtures. The flexibility of this approach allows us to test boundary cases and seldom-hit lines of code with ease. When you couple this with a good coverage tool, like NCover, 100% coverage is feasible. At least, in my opinion :)

Anyway, the point of this post is, more than anything, to give some props to Tim Stall for highlighting the Reflection method of testing private fields, and to throw another opinion out there in the testing sphere.