How To Implement Unit Testing in .NET 5 C# Application

In this post we will discuss how to implement unit testing in .NET 5 C# application.

Unit tests point to code to be tested, automate the process, and verify assumptions made about the code’s behavior.

To ensure you covered all the logic where you have some functionality in your classes, in your method(s) to test classes, include all if, case, do, until, while, and any logic you have in your classes. You can perform a regression test to ensure you’re still passing the functionality when you change the code in one of your methods when you cover it with a test method.

Is it important to write unit tests?

  • For our code to work under different circumstances with different inputs, we need unit test methods.
  • Code quality improves as a result.
  • By breaking code down into smaller chunks, you can focus on quality
  • By handling errors better, you improve the quality of your code 
  • As a result, developers will become less fearful of breaking things with code changes.

Requirements in advance:

A basic understanding of

  • C#
  • Visual Studio

In this article I continue the discussion of a clean architecture for ASP.NET Core that I began in my previous article ASP.NET core application.

Unit test for .NET 5: 

 The writing of unit tests for web APIs should take into account a few things.

  1. We will need to test public API at some point, but in general you need to test public API when you are testing your unit test as a consumer of the code.
  2. Using Dependency Inversion, you can run in isolation
  3. It should produce the same result regardless of the input
  4. Run time of test methods should be as short as possible 
  5. It can be automated by using CI CD pipelines.

 How to set up unit tests:

Set up a test project

Implement Unit Testing in .NET 5

My unit test methods will be developed using Xunit unit. Based on my last article on clean architecture, I have used the application that I created.

Using a framework or manually mocking the data is the best way to test code in isolation so we will follow it.

Packages used

XUnit – The testing framework.

Use Moq to create Moq versions of dependencies

Shouldly – Assertion framework with ease of use

Use NuGet package manager to download all packages.

We can write the unit test method for this class’ handle function if we assume the following code.

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);
        }
    }

To write unit tests for the handle function, we need to mock the IAsyncRepository.

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;
        }
    }

A mocked Async Repository instance will be created, and the mocked repository function will be created for a call. In the ReturnsAsync method, the value to return from ListAllAsync will be specified.

The actual test method is as follows:

 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);
        }
    }

Using automapper and mocked hotel repository field as parameters, the handler instance is executed when GetHotelListTest() is called.

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

The automapper profile is configured with this statement

A profile for AutoMapper

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

To verify that the count is 1, we use this assert function. A Shoudly library function calls ShoudlBe Assertion.

Click on test and select Run all test.

Implement Unit Testing in .NET 5

Closing Thoughts:

It is important to understand what is unit testing, why it should be used and how to implement it with a .NET 5 application. If you have any queries or suggestions feel free to ask in the comments below.

Leave a Comment