Thursday, 5 October 2017

Unit Testing using xUnit

Unit Testing is a level of software testing where individual components of a software are tested. The purpose is to validate that each unit of the software perform its required functionality properly.

In Software development Unit Test methods are written to test the code internally while the code gets executed, it makes the development Test driven. Below is the flow diagram that shows how test method works:
The above diagram makes the flow of unit test execution very clear. So now, we’ll discuss our topic Unit testing using xUnit framework.

xUnit framework helps in writing test methods in .net. The xUnit test runner contains the program entry point to run your tests. Dotnet test starts the test runner using the unit test project you've created.
Below is the basic example to write xUnit Unit test for .net Service:

using System;

namespace Number.Services
{
    public class PrimeService
    {
        public bool IsPrime(int number)
        {
            if (candidate == 1)
          {
            return false ;
          }
            throw new NotImplementedException("Please create a test method");
        }
    }
}
 Each Test method should group these functional sections as shown in the test method below:

1 Arrange all necessary preconditions and inputs.
2 Act on the object or method under test.
3 Assert that the expected results have occurred or not.

using Xunit;
using Number.Services;

namespace Number.UnitTests.Services
{
    public class PrimeService_IsPrime
    {
        private readonly PrimeService _primeService;

        public PrimeService_IsPrime()
        {
            _primeService = new PrimeService();
        }

        [Fact]
        public void ReturnFalseForValue1()
        {
            //Arrange
            var number = 1;

            //Act
            var result = _primeService.IsPrime(number);

            //Assert
            Assert.True(result, false );
        }
    }
}
 The above test will pass as the code in the actual method returns false and we are also checking that if the result is false.

The [Fact] attribute indicates a test method that is run by the test runner. Eexecute dotnet test to build the tests and the class library and then run the tests. 

The above example does not contain dependencies but if the code has dependency on other layers of the project the best practice is to MOQ the dependencies and then test the code.
The above diagram shows how the Mocking is different. MOQ is basically a nuget package that you can use to mockup any dependency. MOQ is the only mocking library for .NET developed from scratch to take full advantage of .NET Linq expression trees and lambda expressions, which makes it the most productive mocking library available.It also supports mocking interfaces as well as classes.

You will get an idea of MOQ in below example. Here, I will explain how we write test methods and mock up dependencies.

namespace Products.Controllers
{

public class ProductController : Controller
    {
        private readonly IProductRepository<Product> _productRepository;

        public ProductController(IProductRepository<Product> productRepository)
        {
            _productRepository = productRepository;
        }

        [HttpGet]
        public IActionResult GetAllProduct()
        {
            var data = _productRepository.GetAll().ToList();

            return View(data);
        }
 The above controller method is dependent on repository layer. So to write test method in such scenarios we need to use MOQ framework, as used in the below example:

 using Moq;
using Xunit;

namespace Products.Tests
{
    public class ProductController Tests
    {
        private ProductController _productController;
        private IProductRepository<Product> _productRepository;

        [Fact]
        public void IndexActionReturnsProductList()
        {
            //Arrange
            var products = GetProductList();
            var mock = new Mock<IProductRepository<Product>>();
            mock
                 .Setup(x => x.GetAll())
                 .Returns(products);

            _productController = new ProductController(mock.Object);

            //Act
           
              var data = _productController.Index() as ViewResult;
              var result = (List<Product>) data.Model;

            //Assert
            Assert.Equal(4, result.Count);
        }

        private IQueryable<Product> GetProductList()
        {
            var product= new List<Product>
            {
                new Product
                {
                     Name = "Car",
                     ProductCode= "0986",
                },
                new Product
                {
                     Name = "Scooter",
                     ProductCode= "0945",
                }             
            };
            return product.AsQueryable();
        }
   }
}

In the test method above, we have mocked the ProductRepository and its method GetAll() and instead get data from private method GetProductList() and do the testing and checking the result for controller layer only.

Conclusion: In this way, you can write test methods for all layers of project (i.e. Controller, Services, Repositories, etc.) by mocking the dependencies. Test driven Development helps to make development more bug free and xUnit framework makes it much easier. Hope with this blog you get an overview of writing test methods using xUnit and MOQ.

About Author:
Shivangi Verma  is a consultant in Systems Plus Pvt. Ltd. Within Systems Plus, she actively contributes to the areas of Technology and Information Security. She can be contacted at: Shivangi.Verma@spluspl.com 

7 comments: