We use cookies to provide you with a great user experience, analyze traffic and serve targeted promotions.   Learn More   Accept
Card image cap

Writing Unit Tests for Void Methods using xUnit, Moq and Dotnet Core CLI - Part One

xUnit Unit Testing  • Posted 8 months ago

So far We have been discussing about Unit Testing and how these tests can help in early detection of logical errors. we have also looked at the two major kinds of unit testing patterns: faking unit tests and mocking unit tests. We have looked in-detail about how Mocking Unit Tests can help at unit testing components with the respective dependencies simulated and how Moq framework helps in achieving mocking dependencies in a simpler way.

When it comes to functionalities which are encapsulated in the form of methods, we have returning methods and void methods. While unit testing a returning method is a simpler deal; testing a void method which does some operation but doesn't return anything to indicate the calling component of its result is dealt in a different way.

Classification of Methods:

Conceptually, there are two types of methods: Interacting methods and Computing methods. These are differentiated based on the method signature; specifically the return type.

Interacting methods are commands using which we instruct the system to do something; like Add or Delete a record, Print a statement and so on. These command methods don't necessarily bear a return type - they don't return anything. A delete command removes a record and it completes its responsibility - there's no need to return anything.

Computing methods are query methods which we use to request the application to return some data: say a list of records for a given criteria or simply fetch all the types which exist in a system. These methods might have a parameter be passed as a criteria but do return data.

Since we have two types of method behaviours, we have two types of unit tests depending on what type of method we are subjecting our tests to:

  1. Interaction Tests :

These test the interaction of a method onto the system. Since these are void methods, we need to verify the invocation of a method within these tests.

  1. Computation Tests :

These test the computation of a method by virtue of its parameters. Since these return data, we can simply assert the returned data against a valid sample set.

Let's look into how we can write such tests in our ReaderApi using xUnit and Moq.

Dotnet CLI and Visual Studio Code:

The latest versions of Visual Studio Code (the light weight cross platform code editor from Microsoft) come integrated with Test Runners and Dotnet Core CLI, and so for this demonstration we shall make use of these tools for development.

Step 1: Create a Test Project:

After pointing to the project folder, open a terminal window and type the below command:

    > dotnet new sln --name ReaderFactoryApp

The command creates a new solution file. Now we add two projects to the created solution. We first create an API project which holds our ReaderFactory and API logic, and another project which contains the test logic.

    > dotnet new webapi --name ReaderFactoryApp.Api --output ./Api
    > dotnet new xunit --name ReaderFactoryApp.Tests ./Tests

The above command creates two new projects under respective folders.

    > dotnet sln ./ReaderFactoryApp.sln add ./Api/ReaderFactoryApp.Api.csproj
    > dotnet sln ./ReaderFactoryApp.sln add ./Tests/ReaderFactoryApp.Tests.csproj

The above commands add the created projects of API and Tests onto the created solution file.

We'd like to test the functionality of ReaderFactory.Create() method which returns a new IReader instance for a given input.

public class ReaderFactory : IReaderFactory
{
    public IReader Create(int tierId)
    {
        IReader reader = null;

        switch(tierId) 
        {
            case 1:
                reader = new TierOneReader();
                break;
            case 2:
                reader = new TierTwoReader();
                break;
            case 3:
                reader = new TierThreeReader();
                break;
            case 4:
                reader = new TierFourReader();
                break;
            default:
                {
                    Print("No Matching Readers Found");
                    reader = new NoReader();
                }
                break;
        }

        return reader;
    }

    public void Print(string message)
    {
        Console.WriteLine(message);
    }
}

Create a new Unit Test file ReaderFactoryUnitTests which holds the unit tests we write for the ReaderFactory class.

public class ReaderFactory_UnitTests
{
    [Fact]
    public void Create_WhenCalled_ReturnsNoReader()
    {
        //Arrange
        var factory = new ReaderFactory();
        int tierId = 5;

        //Act
        var reader = factory.Create(tierId);

        //Assert
        // Assert.IsType(typeof(NoReader), reader);
        Assert.True(reader.GetType() == typeof(NoReader));
    }
}

From the above test method, We can assert the type of returned instance should be NoReader when a tierId of value above four is passed. This a simple example which tests the computation logic of a method and hence this is a computation test.

Now let's consider the functionality at the level of ReaderController.Read() method where we would want to test when the Read() method invokes the method Create() over the factory instance, whether the Print() method is invoked or not.

public class ReaderController : Controller 
{
    [Route("{tierId}")]
    public IEnumerable<Reader> Read(int tierId)
    {
        var reader = factory.Create(tierId);
        return reader.ReadContent();
    }
}

This Print() method is a void method in this case; a command that prints over the console. Since we want to test an invocation of a method which doesn't return any value to assert for variation, this comes under the category of an Interactive Test which we shall look in the next article.

moq void method unit test void method c# unit test void method c# moq create unit test for void method c# xunit test void method how to test void methods c# assert void method c# unit test case for void method in c# unit test for void method c# xunit assert void method c# unit test void method moq mock void method unit test void method moq return void how to write unit test for void method c# test void method c# unit testing void methods assert for void method c# unit testing void methods c# xunit test void method c# how to unit test methods that return void c# unit test verify method called unit testing c# asp.net core