views:

116

answers:

2

I am using an api which interacts with a db. This api has methods for querying, loading and saving elements to the db. I have written integration tests which do things like create a new instance, then check that when I do a query for that instance, the correct instance is found. This is all fine.

I would like to have faster running unit tests for this code but am wondering about the usefulness of any unit test and if they are actually giving me anything. for example, lets say I have a class for saving some element I have via the API. This is psuedo code, but get the idea of how the api I am using works across.

public class ElementSaver
{
    private ITheApi m_api;

    public bool SaveElement(IElement newElement, IElement linkedElement)
    {
        IntPtr elemPtr = m_api.CreateNewElement()
        if (elemPtr==IntPtr.Zero)
        {
            return false;
        }
        if (m_api.SetElementAttribute(elemPtr,newElement.AttributeName,newElement.AttributeValue)==false)
        {
             return false;
        }
        if (m_api.SaveElement(elemPtr)==false)
        {
             return false;
        }

        IntPtr linkedElemPtr = m_api.GetElementById(linkedElement.Id)
        if (linkedElemPtr==IntPtr.Zero)
        {
            return false; 
        }
        if (m_api.LinkElements(elemPtr,linkedElemPtr)==false)
        {
            return false;
        }
        return true;

    }
}

is it worth writing unit tests which mock out the m_api member? it seems that I can test that if any of the various calls fail that false is returned, and that if all of the various calls succeed that true is returned, and I could set expectations that the various methods are called with the expected parameters, but is this useful? If I were to refactor this code so that it used some slightly different methods of the api, but achieved the same result, this would break my tests and I would need to change them. This brittleness doesn't seem very useful.

Should I bother with unit tests for code like this, or should I just stick with the integration tests that I've got?

+2  A: 

It is a good idea to mock out m_api in my code for the following reasons (not all of which apply to your psuedo-code example):

  • As you mentioned, you can verify that your class performs error handling properly
  • In cases where you have more complex code in your class (e.g., cacheing), you can use expectations on your mock to ensure that the class is behaving properly. For example, retrieve the same object twice but ensure that m_api is only called once.
  • Your unit test can test behavior without creating an appropriate data set. This increase maintainability over time as the data model underneath m_api changes.
John Stauffer
+3  A: 

Look at what the tests are like. If you're only testing if stuff that comes in ends up in the database etc. Your probably doing the right thing by only doing automated integration tests. If there's logic you want to test then you might want to look if you can factor out your logic into separate classes that you can unit test and facades around the infrastructure code that contain no logic.

Mendelt