Get Start with .NET 5 C# application unit testing

What is unit testing?

A unit test is a code that will, in an automated way, invoke code to be tested and it will check an assumption about the behavior of the code under test. 

You writing method(s) to test methods in your classes, write test to include all if, case, do, until, while for, and any logic where you have some functionality to make sure you covered. The advantage of covering the method with test method is when you go back in change some code in one out methods, you can perform a regression test, which is you running those tests against to make sure you still passing the functionality.

Why should I write unit test?

  • We should write the unit test methods to ensure our code works under varying circumstance with different inputs.
  • It improves the quality of the code.
  • It helps you focus of quality and break code into smaller chucks
  • You add more error handling which leads to better quality 
  • Developer will get a confident on code changes without getting a fear of breaking something.

Pre-Requests:

Basic Knowledge on

  • C#
  • Visual Studio

This article is continuation of the my previous article on clean architecture for ASP.NET core application.

Unit test for .NET 5: 

 List of things, we need to keep in mind while writing the unit test methods for Web API.

  1. Test public API – Definitely there will be possibility where we need to testing the private API as well, however in general your unit test is consumer of the code and hence you need to test public API
  2. Run in Isolation – This is possible with Dependency inversion
  3. Consistent Result – Whatever the input the result should be same
  4. Fast – test method run time should be less 
  5. Automated – We can include it in CI CD pipeline.

 Setting up Unit Tests :

Create a test project

Class Library
.NET 5

I will be using Xunit unit to develop the unit test methods. I have used the application which was created in my last article on clean architecture.

To Test the code in isolation we need to mock the data manually or using framework.

Packages used

Moq – Use to create Moq version of dependency

 Shouldly – ease to use assertation framework

  xUnit – The testing framework.

  Download all the packages from NuGet package manager.

Project file

Assume below code, let’s write the unit test method to cover the handle function in this class.

    public class GetHotelsListQueryHandler: IRequestHandler<GetHotelsListQuery,List<HotelsListVM>>
    {
        private readonly IAsyncRespository<Hotel> _hotelRepository;
        private readonly IMapper _mapper;
        public GetHotelsListQueryHandler(IMapper mapper, IAsyncRespository<Hotel> hotelRespository)
        {
            _mapper = mapper;   
            _hotelRepository=hotelRespository;
        }
        public async Task<List<HotelsListVM>> Handle(GetHotelsListQuery request, CancellationToken cancellationToken  )
        {
            var allHotels = (await _hotelRepository.ListAllAsync()).OrderBy(x => x.Name);
            return _mapper.Map<List<HotelsListVM>>(allHotels);
        }
    }

We need to mock the IAsyncRepository to write the unit test method for handle function

public static class RespositoryMocks
    {
        public static Mock<IAsyncRespository<Hotel>> GetHotelRepository()
        {
            var concertGuid = Guid.Parse("{12345678-ABCD-12AB-98AD-ABCDF1234512}");
            var hotels = new List<Hotel>{
                new Hotel{HotelId = concertGuid, Name="Gowtham"}
            };
            var mockHotelRepository= new Mock<IAsyncRespository<Hotel>>();
            mockHotelRepository.Setup(repo => repo.ListAllAsync()).ReturnsAsync(hotels);
            mockHotelRepository.Setup(repo => repo.AddAsync(It.IsAny<Hotel>())).ReturnsAsync(
                (Hotel hotel) => {
                 hotels.Add(hotel);
                return hotel;
                });
            return mockHotelRepository;
        }
    }

The above code will create an instance for the Mocked Async Repository, with that instance setup the mocked repository function for a call and in the ReturnsAsync specify the value to return from ListAllAsync method.

Actual test method:

   public class GetHotelsListQueryHandlerTests
    {
        private readonly IMapper _mapper;
        private readonly Mock<IAsyncRespository<Hotel>> _mockHotelRepository;

        public GetHotelsListQueryHandlerTests()
        {
            _mockHotelRepository = RespositoryMocks.GetHotelRepository();
            var configurationProvider= new MapperConfiguration(cfg=> cfg.AddProfile<MappingProfile>());
            _mapper=configurationProvider.CreateMapper();

        }
        [Fact]
        public async Task GetHotelListTest()
        {
            var handler = new GetHotelsListQueryHandler(_mapper, _mockHotelRepository.Object);
            var result = await handler.Handle(new GetHotelsListQuery(), CancellationToken.None);
           
            result.Count.ShouldBe(1);
        }
    }

The handler instance has been created to execute the handle method in GetHotelListTest() by passing automapper and mocked hotel repository field as a parameter.

var configurationProvider= new MapperConfiguration(cfg=> cfg.AddProfile<MappingProfile>());
 _mapper=configurationProvider.CreateMapper();

This statement is used to configure the automapper profile

AutoMapper Profile

  public class MappingProfile: Profile
    {
        public MappingProfile()
        {
            CreateMap<Hotel, HotelsListVM>();
        }
      }
result.Count.ShouldBe(1);

This assert function is used to check the count is 1. ShoudlBe Assertion function is from Shoudly library.

Go to test-> Run all test

Run All Test Visual Studio

Summary:

 We have seen what is unit test method, why should we use unit test method and how to implement with .NET 5 application.

Source code – GitHub

 Happy Coding!!! 

gowthamk91

Leave a Reply

Discover more from Gowtham K

Subscribe now to keep reading and get access to the full archive.

Continue reading