Should: Func’y Testing

When it comes to testing anything, testing methods (or functions) is probably the test performed most. I know that most of the time, I want to know if the function I just wrote is going to do what I want it to do:

  1. Will it return the correct value?
  2. Will it return the correct type?
  3. Will it throw an exception?
  4. Will it throw anything else? (like a tantrum)
  5. If it doesn’t return anything, does it perform it’s actions successfully?

These are a few of the things I constantly find myself testing, and I’m sure other people do too. After all, this is what Test-Driven Development (TDD) was created for. I have to admit, because of my previously-mentioned fussiness with current .NET testing frameworks and procedures, I’ve resorted to things like writing console apps to test output, creating obscure debugging classes to record information, and writing messy debug code that eventually just gets deleted.

Current testing procedure seems to follow along all the same lines. Create a class to hold test functions that test specific methods or parts of that class. Once you have all these functions set up, your usual next step would be to fill them with instances of your test class, a few parameters if any are needed, some test data and some assertions.

The problem here is the incredible amount of repetition. Clearly those who designed .NET testing frameworks had never heard of DRY (dont-repeat-yourself).

Now, what if all that could be done in one line? This is where Expectation Tests come in. I mentioned these in my previous post and went over their syntax, and I’m definitely still in the concept stages as I write this, but I’ve discovered that you can do just that:

this.Expects(Context.someFunction(), "should return true"); 

Note: here, this is a class that implements IShouldTest<T> where T is the class, or the “context”. Within this test class, there is a property called Context which obviously points to your passed context, which is instantiated automatically on every test run. You don’t have to do that yourself every time.

Now, this singular line hides a lot of workings behind the scenes, just like a good framework should, but it’s also incredibly powerful. What we’re saying here is that this test context expects the function Context.someFunction() to return true. In one fell swoop we’ve provided the code to test, the expected test parameters and made the test framework aware of the test. Easy peasy.

The concept behind it is pretty simple. Why should I have to specifically define every single element of my test, every single time? Why can’t I just say “I want to test this, this is what it should do”?

This is all made possible due to the improvements in how delegates are used in .NET. I must admit, for a while I just didn’t understand why you’d want to use a delegate, apart from async and event stuff, and the massive waste of time setting these things up was a huge put-off for me personally. Since Func<T> and it’s cousinAction<T> turned up, you can now leave all the annoying delegate work to the framework. It performs all the necessary creation of delegate types for you, and the best thing about this is that it isn’t doing anything more than it used to, so there’s no performance hit.

Another reason why testing using Func<T> and it’s friends is great is LINQ and Lambda. Have you ever wondered, ‘how would my function react if i gave it this?’:

this.Expects((hugeDictionary) => someSortingFunction(hugeDictionary), "should take < 1 minute"); 

Pretty cool, huh?

Advertisements