Saturday, June 02, 2007

How to unit test the unit untestable?

Hey.

Isn't it funny how all the unit test propaganda tries to get to you with their really complex examples? This isn't far from the average source code illustration you're presented with:

  [Test]
public void TestAdd()
{
Assert.AreEqual(3, Add(1, 2));
}

public int Add( int one, int two )
{
return one + two;
}
Yeah, ok. I see, the TestAdd() test tries to call the Add method with the parameters '1' and '2'? And then checks if the result is 3? Nice. I'm sure that unit test is going to save me hours of debugging the next time I have a refactoring-fest.Ok, so maybe this started out sounding a little more negative than I intended. I know that is not the full extent of the capabilities of unit testing, but it also illustrates part of my point; Unit testing is very simple with methods (functions, anybody?) that takes one or more parameters and returns a predictable value. Sounds like a good, old pure function.

So what about when you have something that depends on some kind of global/static state? Or external resources? What about the property that returns a new value each time you call it - by design - so that each caller will get it's own "atomic" integer?

What if I have a library that ultimately - if all is well - plays a sound to the user? Sure, I can check that it throws an exception if the filename argument is null or the file doesn't actually exist. But how do I check that the sound is actually played? In my unit test, I mean. I know I can listen to the sound coming from my PC.

And what if I need to make a TCP connection to something out there on the scary Internet? There's no knowing how many different fault situations could happen out there - if I try to download a file off the web, how do I know for sure I have tested for everything that could go wrong? How can I unit test that on my laptop while on a flight with no connection?

Does writing a mock object using one of the several availible mock frameworks really help? What does that verify? That I can write a mock object that conforms to the expectations in my test? Do you want me to write a mock of the web or the SQL server just so I can have a test that proves that the mock, the test and the code - all written by the same me - does whatever it does, which may or may not what it is SUPPOSED to do?

I'm asking not to bash or belittle these concepts - I am asking because I don't know and would really like to learn. And I am asking in a very sarcastic way because I'm a bitching, moaning pain in the ass with no patience and an apparent complete lack of regard for people who knows stuff a LOT better than me.

No wonder nobody loves me.

No comments: