MbUnit CsvDataAttribute

MbUnit has several cool features which distinguish it from some of the other unit testing frameworks on the .NET platform. Among them are the RollbackAttribute, PrincipalAttribute, ThreadedRepeatAttribute, and the Csv/XmlDataAttribute.

I hadn’t noticed the CsvDataAttribute previously when I’ve worked with MbUnit, but it’s definitely one that I think that most teams can make the most use of. While the RowAttribute allows developers to externalize and parameterize their unit tests, the CsvDataAttribute takes it to another level by allowing developers to put test parameters in a simple text file. This is extremely handy since it becomes easier to add more test conditions as you come up with new scenarios without recompiling code. Theoretically, you could even involve your QA team in getting the right set of test data since they could modify the external CSV file. I find this extremely handy 🙂

The documentation on how to use it was lacking a bit; while it explained that you can add metadata (custom attributes) via the CSV file, it didn’t give an example for the ExpectedExceptionAttribute, one of the most common ones, I’d imagine.

Consider the following property which normalizes and validates a phone number (note: this was meant as a simple example):

The test method might look like this:

Now we’d like to test our validation logic to gaurd against future refactorings to make sure that anyone refactoring this code throws the appropriate exceptions that our downstream callers expect.

You can see that I’ve used the FilePath property and the HasHeader property (you have to use this if there is a header, otherwise, it detects the header as a row; it’s not true by default it seems). The text file to go with this test would then look like:

There are a few things to note here:

  1. If no exceptions are associated with the row, don’t include a trailing comma and empty value (see the first line).
  2. The headers are not case sensitive.
  3. Null values can be specified using an empty value.
  4. When specifying exceptions, you do not need to use typeof(ArgumentException), just the type is enough.

Happy (unit) testing!

You may also like...