C# standardizing tests - Part 3

Let's start with fixture service implementation

Implementing IDisposible

Our fixture service will be called multiple times during the execution of the tests by the ClassFixture. It is the most important service in our implementation as it will communicate directly with the test and deliver everything the test needs.

So it is advisable to implement the inheritance of the IDisposable to recycle memory in each execution destroying the objects or instances of services that we use inside. In addition to this, we avoid some of our test failures for having obsolete data in some of the services.

This method would be placed at the bottom of the private method region and we will also use the protected region.

In our case, the service to test contains 3 services that we will use later, so we can destroy them. There are many ways to do it, for example in the following way:

...

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}
#endregion

#region Protected Methods
protected void Dispose(bool disposing)
{
    if (disposing)
    {
        _utilities = null;
        _urlUtils = null;
        _qrBuilder = null;
    }
}
#endregion

Builder Pattern into Fixture Service

Having to validate all the paths that our MetadataService may have in lines of code, we know that we also have to test the constructor methods.

By including the previous validations in the constructor method we can perform two tests, one of which is the happy path, which returns the instance created because it has the correct injection of each of the defined services.

And the other test becomes several tests that should include all the possible erroneous combinatorics or services not injected null.

In our case, there would be 3 tests to validate in each one that the result is an exception because one of the services has not been injected and has arrived null.

But what would happen if our service no longer had 3 injected services but 6 or 7, or worse, more than 7 injected services, which is no longer advisable but can occur?

For these cases, we must work the fixture to allow to establish the services in an agile way and in addition to this we will use later a strategy to pass all the combinatorics in a single test. First, in our case, we have used a design pattern called Builder Pattern within the fixture service. How do we do it?

It is easy, we create a method called reset() that will be initialized with the constructor method of the fixture service and is responsible for setting the desired default value of all services that will be stored in the fixture as protected properties, in our case, all will be Mocking.

The following is to establish a method with the same name "SetService" but with different signatures, each one of them must correspond to the corresponding service.

This method is in charge of setting the value to each service and returning an instance of the same fixture service, which now will already have a new service established.

When the test class asks the fixture for the instance of the class to test with the GetSut() method, the fixture will create a new instance passing each one of the protected services of the fixture class.

Let's see what our fixture service looks like:

public class MetadataServiceFixture : IDisposable
{
    #region Properties
    protected IUtilities _utilities;
    protected IUrlUtils _urlUtils;
    protected IQRImageBuilder _qrBuilder;
    #endregion

    #region Constructor Method
    public MetadataServiceFixture()
    {
        Reset();
    }
    #endregion

    #region Public Methods
    public void Reset()
    {
        _utilities = new Mock<IUtilities>().Object;
        _urlUtils = new Mock<IUrlUtils>().Object;
        _qrBuilder = new Mock<IQRImageBuilder>().Object;
    }

    public MetadataServiceFixture SetService(IUtilities utilities)
    {
        _utilities = utilities;
        return this;
    }

    public MetadataServiceFixture SetService(IUrlUtils urlUtils)
    {
        this.urlUtils = urlUtils;
        return this;
    }

    public MetadataServiceFixture SetService(IQRImageBuilder imageBuilder)
    {
        this.imageBuilder = imageBuilder;
        return this;
    }

    public MetadataService GetSut()
    {
        return new MetadataService(_utilities, _urlUtils, _qrBuilder);
    }

...

We will start with the implementation of the tests using this fixture service. See you in part 4...

0
Subscribe to my newsletter

Read articles from Jaime Andrés Quiceno González directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jaime Andrés Quiceno González
Jaime Andrés Quiceno González

I am motivated Software and Telecommunications Engineer with 9 years of experience in analysis, design, implementation, testing and deployment of software solutions. I am passionate about knowing the context of the problem in detail to end an adequate solution applying SOLID principles and design patterns to deliver software products with quality and efficiency. I have supported and innovated with automation various business and industrial processes through several programming languages and work frameworks with and without Agile methodologies. I have skills and knowledge in both FrontEnd and BackEnd.