Thursday 27 September 2012

Unittesting third-party libraries

In Uncle Bob's Clean Code, which I can dearly recommend, he's writing about unit tests and TDD. Nothing new under the sun here.
What was new for me, was the part where he points out it can be a good idea to unittest a third party library. As I'm used to only put the public methods under test and mock out third party calls the idea made me frown at first.
It’s not our job to test the third-party code, but it may be in our best interest to write tests for the third-party code we use.
Of course one shouldn't adopt everything he reads without putting some thought in it first, even coming from a renowned author such as Robert Martin.
Nonetheless there are some strong arguments in favor:
  • When you have to learn a new library you have to play with it to get acquainted to it, doing this in unittests instead of production code lets you focus on the library itself.
  • When upgrading the library to a new version you at least know the methods under test still behave the same way.
  • You get a documentation that's always up to date with it as well.
And all this comes at the same cost you already had to pay learning the library.

Recently I had to implement a report functionality which generated a pdf. The choice was made to use the iTextSharp library so this was an ideal moment to put theory into practice.
The first problem I encountered was the assertion of my tests. How could I verify if a correct pdf was created? I needed to be able to parse a pdf file to achieve this. Looking further into the iTextSharp library I discovered it was more or less possible using the same library.
But would that make any sense? Although the assert-logic wouldn't use the same methods of the library, the question arose if it was a good idea to write tests where the assert uses the same library as the act part.

Writing following kind of tests would be quite ridiculous.
[TestFixture]
public class WhenSomeAction
{
    private int result;

    [SetUp]
    public void SetUp()
    {
        //arrange
        var sut = new SystemUnderTest();
        //act
        result = sut.SomeAction();

    }

    [Test]
    public void ShouldResultIntoSomething()
    {
        var sut = new SystemUnderTest();
        var expectedResult = sut.SomeAction();
        Assert.AreEqual(expectedResult, result);
    }
}
Given my asserts didn't use the same logic of the library I proceeded this way. In the end I wasn't going to include another pdf library just for testing purposes and definitely wasn't going to write one myself.
Finally I ended up with a couple of unittests (the pdf's that had to be created were rather simple) for creating a document, a footer, a header and a table.

I'm curious about the day we decide to upgrade the iTextSharp library. Unfortunately it's probable that I'll have to modify the assert logic of my tests once the library changes.