Grasshopper Unit testing

“I have created my code, split out some functionality and written the tests. But the mocks have become a real mess, and much more work than I had thought it would be. Can you help me, Sensei?”

“Of course. Show me your code, grasshopper”

The code is a validator class with different validation methods. The public functions in this class would perform the validations, and in turn call some private methods to retrieve data from the database.

“How can I test these private methods, sensei?”

“Usually, if you have private methods that need to be tested, that’s a code smell already. It isn’t always bad, but it could indicate more problems. Using the PrivateObject class can help you with this.”

The validators would first call some of the private methods, then perform some trivial additional tests and then return the validation result as a Boolean. So to test the actual validation methods the private methods were put as public (smell) and then stubbed. So something was going wrong here. But my young apprentice came with a very good answer:

“But sensei, if stubbing out methods in a class to test other methods in the same class smells so hard, wouldn’t it be a good idea then to move these methods into a separate class?”

Now we’re talking! The Validation class was actually doing 2 separate things. It was

  1. validating input
  2. retrieving data from the database

This clearly violates the “Separation of Concerns” principle. A class should do one thing. So let’s pseudo-code our example:

public class Validator
{
    public bool CanDeleteClient(Client x)
    {
        bool hasOrders = HasClientOrders(x);
        bool hasOpenInvoices = HasOpenInvoices(x);
       
        return !hasOrders && !hasOpenInvoices;
    }
   
    public bool CanUpdateClient(Client x)
    {
        bool hasOpenInvoices = HasOpenInvoices(x);
       
        return !hasOpenInvoices;
    }
   
    public bool HasClientOrders(Client x)
    {
        // Get orders from db
        // …
    }
   
    public bool HasOpenInvoices(Client x)
    {
        // Get invoices from db
        // …
    }
}

In the tests the HasClientOrders and HasOpenInvoices functions were stubbed so no data access would be required. They were actually put public to make it possible to test them.

So splitting this code out in 2 classes makes testing a lot easier. Here is a drawing of what we want to achieve:

image

Show me the code

interface IValidatorRepo
{
    bool HasClientOrders(Client);
    bool HasOpenInvoices(Client);
}

public class ValidatorRepo : IValidatorRepo
{
    public bool HasClientOrders(Client) { … }
    public bool HasOpenInvoices(Client) { … }
}

public class Validator
{
    IValidatorRepo _repo;
    public Validator()
    {
        _repo = new ValidatorRepo();
    }
   
    public Validator(IValidatorRepo repo)
    {
        _repo = repo;
    }

    public bool CanDeleteClient(Client x)
    {
        bool hasOrders = _repo.HasClientOrders(x);
        bool hasOpenInvoices = _repo.HasOpenInvoices(x);
       
        return !hasOrders && !hasOpenInvoices;
    }
   
    public bool CanUpdateClient(Client x)
    {
        bool hasOpenInvoices = _repo.HasOpenInvoices(x);
       
        return !hasOpenInvoices;
    }
}

What have we achieved by this? We now have 2 classes and 1 interface instead of just 1 class. There seems to be more code, and it looks more complex…

But the class Validator violated the “Separation of Concerns” principle. Instead of only validating, it was also accessing the data. And this we now have fixed. The ValidatorRepo class does the data access, and it is a very simple class. The Validator class just checks if a client has orders or open invoices, but it doesn’t care how this is done.

Notice that there are 2 constructors: The default constructor will instantiate the actual ValidatorRepo, and the second version takes the IValidatorRepo interface. So now in our test program we can create a class that just returns true / false in any combination that we like, and then instantiate the Validator with this.

In the Validator we then just call the methods on the interface, again “not caring” how they are implemented. So we can test the Validator implementation without needing a database. We don’t have to stub functions in our function under test, so the air is clean again (no more smells).

“Thank you sensei. But it seems that this is something very useful, so I would think that somebody would have thought about it already?”

“Yes, this principle is called Dependency Injection, and it is one of the ways to achieve testable classes, by implementing Separation of Concerns.”

About Gaston

MCT, MCSD, MCDBA, MCSE, MS Specialist
This entry was posted in .Net, Codeproject, Development, Methodology, Testing and tagged , , . Bookmark the permalink.

3 Responses to Grasshopper Unit testing

  1. Pingback: Mocking functionality using MOQ | MSDev.pro blog

  2. Pingback: Unit testing your Repositories | MSDev.pro blog

  3. Pingback: Structuring an MVC app for easy testing | MSDev.pro blog

Leave a comment