Web API – Unit Tests

In this post, we will see how to implement Unit Tests for the Web API created in the post:
Docker – Web API and Sql Server.


First of all, we open Visual Studio and we add a xUnit Test Project called TestWebApiServices:




Then, we add a file called UserControllerUnitTests, where we will define all objects that we will use for testing the services:

[UserControllerUnitTests.cs]

using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;
using WebAPIDocker.BE_UI;
using WebAPIDocker.BLL;
using WebAPIDocker.Controllers;
using WebAPIDocker.DAL;

namespace TestWebAPIServices
{
    public class UserControllerUnitTests
    {
        readonly DataContext objDataContext;
        readonly UnitOfWork objUnitOfWork;
        readonly UserCore objUserCore;
        readonly UsersController _service;

        public UserControllerUnitTests()
        {
            DbContextOptions<DataContext> options;

            // definition of Database in memory
            var builder = new DbContextOptionsBuilder<DataContext>().UseInMemoryDatabase(databaseName: "TestDB")
                                .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

            options = builder.Options;
            objDataContext = new DataContext(options);
            objUnitOfWork = new UnitOfWork(objDataContext);
            objUserCore = new UserCore(objUnitOfWork);

            // Definition of UserController
            _service = new UsersController(objUserCore);
        }

        private async Task FeedDbInMemory()
        {
            var countUser = await objUserCore.GetUsersCount();
            if (countUser == 0)
            {
                User objUser = null;

                for (int i = 1; i < 18; i++)
                {
                    objUser = new User();
                    objUser.Id = i;
                    objUser.UserName = $"UserName_{i}";
                    objUser.Password = $"Password{i}";
                    objUser.CreatedAt = DateTime.Now.AddDays(-i).ToShortDateString();
                    await objUserCore.AddUser(objUser);
                }
            }
        }
    }
}



Now, we can test all UserController’s methods:


GETALLUSERS

[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetAllUsers()
{
     var result = await _coreUser.GetAllUsers();
     if (result == null || result.Count == 0)
     {
         return NotFound();
     }
     return Ok(result);
}


Tests:

[Fact]
public async Task GetAllUsers_WithoutUsersIntoDB_ShouldReturnNotFound()
{
    // Arrange
    objDataContext.Database.EnsureDeleted();
    
    // Act
    var controllerResult = await _controllerUser.GetAllUsers();

    // Assert
    Assert.IsAssignableFrom<NotFoundResult>(controllerResult.Result);
}


[Fact]
public async Task GetAllUsers_WithUsersIntoDB_ShouldReturnOk()
{
    // Arrange
    Task.Run(() => FeedDbInMemory()).Wait();

    // Act
    var controllerResult = await _controllerUser.GetAllUsers();
    var lstUsers = ((OkObjectResult)controllerResult.Result).Value as IEnumerable<User>;

    // Assert
    Assert.IsAssignableFrom<OkObjectResult>(controllerResult.Result);
    Assert.Equal(17, lstUsers.Count());
}



GETUSERBYID

[HttpGet("{id}")]
public async Task<ActionResult<User>> GetUserById(int id)
{
    var result = await _coreUser.GetUserById(id);

    if (result == null)
    {
        return NotFound();
    }

    return Ok(result);
}


Tests:

[Fact]
public async Task GetUserById_WithUserIdNotValid_ShouldReturnNotFound()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();

     // Act
     var controllerResult = await _controllerUser.GetUserById(100);

     // Assert
     Assert.IsAssignableFrom<NotFoundResult>(controllerResult.Result);
}


[Fact]
public async Task GetUserById_WithUserIdValid_ShouldReturnOk()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();
     var idUser = (await objUserCore.GetAllUsers())[0].Id;

     // Act
     var controllerResult = await _controllerUser.GetUserById(idUser);
     var objUser = ((OkObjectResult)controllerResult.Result).Value as User;

     // Assert
     Assert.IsAssignableFrom<OkObjectResult>(controllerResult.Result);
     Assert.Equal($"UserName_{idUser}", objUser.UserName);
     Assert.Equal($"Password{idUser}", objUser.Password);
}



DELETEUSERBYID

[HttpDelete("{id}")]
public async Task<ActionResult> DeleteUserById(int id)
{
     var result = await _coreUser.DeleteUser(id);

     if (result == false)
     {
         return NotFound();
     }

     return Ok();
}


Tests:

[Fact]
public async Task DeleteUserById_WithUserIdNotValid_ShouldReturnNotFound()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();

     // Act
     var controllerResult = await _controllerUser.DeleteUserById(100);

     // Assert
     Assert.IsAssignableFrom<NotFoundResult>(controllerResult);
}


[Fact]
public async Task DeleteUserById_WithUserIdValid_ShouldReturnOk()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();
     var idUser = (await objUserCore.GetAllUsers())[0].Id;

     // Act
     var controllerResult = await _controllerUser.DeleteUserById(idUser);

     // Assert
     Assert.IsAssignableFrom<OkResult>(controllerResult);
}



ADDUSER

[HttpPost]
public async Task<ActionResult> AddUser(User inputUser)
{
     var result = await _coreUser.AddUser(inputUser);

     if (result == false)
     {
         return NotFound();
     }

     return Ok();
}


Tests:

[Fact]
public async Task AddUser_ShouldReturnOk()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();
     User objUser = new User();
     objUser.UserName = "UserNameTest";
     objUser.Password = "PasswordTest";
     objUser.CreatedAt = DateTime.Now.ToShortDateString();

     // Act
     var controllerResult = await _controllerUser.AddUser(objUser);

     // Assert
     Assert.IsAssignableFrom<OkResult>(controllerResult);
}



EDITUSER

[HttpPut]
public async Task<ActionResult> EditUser(User inputUser)
{
     var result = await _coreUser.EditUser(inputUser);

     if (result == false)
     {
          return NotFound();
     }

     return Ok();
}


Tests:

[Fact]
public async Task EditUser_WithUserNotValid_ShouldReturnNotFound()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();
     User objUser = new User();
     objUser.Id = 100;
     objUser.UserName = "UserNameTest";
     objUser.Password = "PasswordTest";
     objUser.CreatedAt = DateTime.Now.ToShortDateString();

     // Act
     var controllerResult = await _controllerUser.EditUser(objUser);

     // Assert
     Assert.IsAssignableFrom<NotFoundResult>(controllerResult);
}


[Fact]
public async Task EditUser_WithUserValid_ShouldReturnOk()
{
     // Arrange
     Task.Run(() => FeedDbInMemory()).Wait();
     User objUser = (await objUserCore.GetAllUsers())[0];

     // Act
     var controllerResult = await _controllerUser.EditUser(objUser);

     // Assert
     Assert.IsAssignableFrom<OkResult>(controllerResult);
}



Now, if we run all the tests, using Test Explorer, this will be the result: