Fullstack Hub

[Count: 2]

We are done with server and client-side development in previous parts, our application is fully functional and we are now able to view, add, update, and delete the users. In this part, let’s start implementing the unit and integration tests for Application, Persistence, and Web projects.
In this part, we will write test cases for UserManagement.Application project to test the user queries, commands, and their corresponding validators.

Let’s Start

Let’s start with the Application’s project unit testing. Just to remind you, the Application project contains the business logic, and using the CQRS and Mediator pattern, we have commands for add, update, and delete operations and queries to return the data. We are also using the FluentValidation package to validate the input request and sending back the configurable error messages for invalid requests. For each command or query, we have few dependencies e.g. ConfigConstant(load the values from appsettings.json file), Mapper, and UnitOfWork classes to map the entities e.g. DTO to VM, etc., and to call the functions from UserRepository (through UnitOfWork class) to perform database operations.

Since we are going to develop the unit tests we need to mock all the dependencies to fully focus on user command or query testing. We will see how we will mock the Mapper, ConfigConstant, UserRepository, and UnitOfWork classes through the Moq package and how this loosely coupled architecture (mostly through using interfaces) helps us to achieve our unit testing goals.

UserManagement.Application Unit Tests

In the tests folder, create a new project from MSTest Test Project (.NET Core) template and name it UserManagement.Application.UnitTests. Delete the default UnitTest1.cs class. Before moving forward, install the following dependencies so that we do get any error in upcoming steps:

  • AutoMapper 10.1.1
  • Moq 4.14.5
  • Shouldly 3.0.2
  • xunit 2.4.1
  • xunit.runner.visualstudio 2.4.3
  • Add UserManagement.Application project reference

Create a new folder in UserManagement.Application.UnitTests project and name it User, in the User folder, create two sub-folders Commands and Queries to save corresponding tests.

Create a Base Test Fixture

The basic purpose to create a fixture class is to facilitate the fixed testing environment so that the test results are repeatable. We will use the base fixture class to specify the constant values to required dependencies e.g. IMapper Mapping Profile. This base fixture would be used as a base class for all the module-specific fixture classes, in our class UserFixture. Create a BaseFixture class in the root of the project and replace its content with the following:

namespace UserManagement.ApplicationTests
{
    using AutoMapper;
    using System.Data;
    using UserManagement.Application.Common.Mappings;
    public class BaseFixture
    {
        public IMapper Mapper { get; }
        public IDbConnection DBConnection { get; }
        public BaseFixture()
        {
            var configurationProvider = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<MappingProfile>();
            });
            this.Mapper = configurationProvider.CreateMapper();
        }
    }
}

In previous parts, we went through the MappingProfile class that will help to seamlessly map the entities in commands and queries classes. We will send the Mapper property to the dependency wherever required.

Create User Test Fixture

After creating the BaseFixture, let’s create a user module-specific fixture class to mock the UserRepository function and ConfigConstant class properties value. Thanks to ASP.NET Core built-in dependency injection functionality, IUserRepository interface, and Moq package through which we can mock the function’s input, output and inject them to User command and query wherever required. In the User folder, create a new class UserFixture and replace its content with the following code:

namespace UserManagement.ApplicationTests.User
{
    using Moq;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Domain.Repositories;
    using UserManagement.Domain.UnitOfWork;
    using Xunit;
    public class UserFixture : BaseFixture
    {
        public IConfigConstants Constant { get; }
        public IUnitOfWork UnitOfWork { get; }

        public UserFixture()
        {
            var mockConstant = new Mock<IConfigConstants>();
            mockConstant.SetupGet(p => p.MSG_USER_NULLUSERID).Returns("User Name is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLFIRSTNAME).Returns("First Name is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLLASTNAME).Returns("Last Name is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLDOB).Returns("DOB is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLGENDER).Returns("Gender is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLEMAILADDR).Returns("Email is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLPHNUM).Returns("Phone Number is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLCITY).Returns("City is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLSTATE).Returns("State is required!");
            mockConstant.SetupGet(p => p.MSG_USER_NULLCOUNTRY).Returns("Country is required!");
            Constant = mockConstant.Object;

            var mockUserRepo = new Mock<IUserRepository>();
            var mockUnitOfWork = new Mock<IUnitOfWork>();
            MockAddUser(mockUserRepo);
            MockUpdateUser(mockUserRepo);
            MockDeleteUser(mockUserRepo);
            MockGetAllUser(mockUserRepo);
            MockGetUser(mockUserRepo);
            mockUnitOfWork.SetupGet(repo => repo.Users).Returns(mockUserRepo.Object);
            UnitOfWork = mockUnitOfWork.Object;
        }

        private Mock<IUserRepository> MockAddUser(Mock<IUserRepository> mockRepo)
        {
            mockRepo.Setup(p => p.AddUser(It.IsAny<UserManagement.Domain.Entities.User>())).Returns(Task.Run(() => 100));
            return mockRepo;
        }

        private Mock<IUserRepository> MockUpdateUser(Mock<IUserRepository> mockRepo)
        {
            mockRepo.Setup(p => p.UpdateUser(It.IsAny<UserManagement.Domain.Entities.User>())).Returns(Task.Run(() => true));
            return mockRepo;
        }

        private Mock<IUserRepository> MockDeleteUser(Mock<IUserRepository> mockRepo)
        {
            mockRepo.Setup(p => p.DeleteUser(100)).Returns(Task.Run(() => true));
            return mockRepo;
        }

        private Mock<IUserRepository> MockGetAllUser(Mock<IUserRepository> mockRepo)
        {
            mockRepo.Setup(p => p.GetAllUsers()).Returns(Task.Run(() => GetUserList()));
            return mockRepo;
        }

        private Mock<IUserRepository> MockGetUser(Mock<IUserRepository> mockRepo)
        {

            mockRepo.Setup(p => p.GetUser(110)).Returns(Task.Run(() => GetUserList().FirstOrDefault(u => u.UserID == 110)));
            mockRepo.Setup(p => p.GetUser(100)).Returns(Task.Run(() => GetUserList().FirstOrDefault(u => u.UserID == 100)));
            return mockRepo;
        }

        private IEnumerable<Domain.Entities.User> GetUserList()
        {
            return new List<Domain.Entities.User>
            {
                new Domain.Entities.User
                {
                    FirstName = "John",
                    LastName = "Doe",
                    City = "Falls Chruch",
                    Country = "USA",
                    State = "VA",
                    Zip = "22044",
                    DateAdded = new System.DateTime(2019,01,01),
                    DOB = new System.DateTime(1980,01,01),
                    EmailAddress = "jdoe@fullstackhub.io",
                    Gender = "M",
                    PhoneNumber = "444-443-4444",
                    UserID = 100
                },
                 new Domain.Entities.User
                {
                    FirstName = "Lina",
                    LastName = "Smith",
                    City = "Fairfax",
                    Country = "USA",
                    State = "VA",
                    Zip = "22019",
                    DateAdded = new System.DateTime(2012,01,01),
                    DOB = new System.DateTime(1999,01,01),
                    EmailAddress = "lsmith@fullstackhub.io",
                    Gender = "F",
                    PhoneNumber = "333-443-7777",
                    UserID = 110
                }
            };
        }
        [CollectionDefinition("UserCollection")]
        public class QueryCollection : ICollectionFixture<UserFixture>
        {
        }
    }
}

We have Constant and UnitOfWork interface properties that we would initialize with concrete class objects in the constructor.

In the UserFixture constructor, we are creating the local variable mockConstant of Mock class with IConfigConstants data type. By using the SetupGet function, we are initializing all properties of ConfigConstants properties and after that, initializing class variable Constant that we will send as a dependency to User command or query.

After initializing ConfigConstants class object, next, we are initializing UserRepository functions, since we are accessing UserRepository through UnitOfWork class (to treat UserRepository pure in-memory database), we are creating two mock variables for user repository and unit of work classes. To keep the code clean, I am creating the mock function for each UserRepository function and sending the mockUserRepository as an input parameter. In each function, using the Moq package Setup method, we are specifying the input and return value e.g. in the MockGetUser function, we are specifying if the user would enter 100 as an input value for userId parameter, then send the first item in the user list defined in GetUserList() function where userId is 100 and so on.

In the end, we are declaring the test collection to apply it to all User command and queries test classes. Mouse hover on ICollectionFixture<UserFixture> to understand it’s purpose. It is used to decorate the test classes that it has pre-text-collection fixture data as we defined in BaseFixture and UserFixture classes. To get the fixture data, we would be getting the UserFixture instance through the test classes constructor (like ASP.NET Core built-in dependency injection we been using in previous parts a lot). You will this in action in commands and queries test classes.

User Queries Unit Tests

We created the test fixture classes to mock the dependencies required to properly test the User queries and command, let’s start the Application project unit testing and start with the GetAllUserQuery class that returns all the Users. In the User -> Queries folder, create a new class GetAllUserQueryTest and replace its content with the following:

using AutoMapper;
using Microsoft.Extensions.Logging;
using Shouldly;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UserManagement.Application.Common.Interfaces;
using UserManagement.Application.User.Queries;
using UserManagement.Application.User.VM;
using UserManagement.Domain.UnitOfWork;
using Xunit;

namespace UserManagement.ApplicationTests.User.Queries
{
    [Collection("UserCollection")]
    public class GetAllUserQueryTest
    {
        private readonly IConfigConstants constant;
        private readonly IMapper mapper;
        private readonly ILogger logger;
        private readonly IUnitOfWork unitOfWork;

        public GetAllUserQueryTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
            mapper = userFixture.Mapper;
            logger = userFixture.Logger;
            unitOfWork = userFixture.UnitOfWork;
        }

        [Fact]
        public async Task Handle_ReturnsCorrectVM()
        {
            var query = new GetAllUserQuery();
            var handler = new GetAllUserQuery.GetAllUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(query, CancellationToken.None);
            result.ShouldBeOfType<UserVM>();
        }

        [Fact]
        public async Task Handle_ReturnTwoRecords_WhenRun()
        {
            var query = new GetAllUserQuery();
            var handler = new GetAllUserQuery.GetAllUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(query, CancellationToken.None);
            result.UserList.Count().ShouldBe(2);
        }
    }
}

On a top, we are specifiying the collection name so that we can use the fixture data as we understood in previous step. Next, we are declaring three private variables of IConfigConstants, IMapper, IUnitOfWork type and initilizing them in constructor from UserFixture class’s object.

We have two test cases wherein the first test case we are testing the GetAllUserQuery to see if it returning the UserVM type object. You can see that we are passing mock constant, mapper, and unitOfWork objects to GetAllUserHandler class constructor that means that instead of calling the actual UserRepository functions(that talks to the database), it will call a mocked function that we defined in UserFixture (MockGetAllUser() function) that always would return two hardcoded Users we initialized in GetUserList() function.

In the second test Handle_ReturnTwoRecords_WhenRun(), we are checking the content of the result UserVM and verifying that it has two user records. Remember, that is one of the purposes of defining fixture class to have a fixed testing environment each time we run the test. Just imagine, if you don’t mock the UserRepository and talk to the actual database to verify the user count, you wouldn’t be able to guarantee the count because it may get updated, deleted, or added during other testings.

Next, let’s create the tests for GetSingleUserQuery class where we are passing a userId as an input request and getting a single user record if successfully found from the database. Create a new class GetSingleUserQueryTest in the same User -> Queries folder and replace its content with the following:

namespace UserManagement.ApplicationTests.User.Queries
{
    using AutoMapper;
    using Shouldly;
    using System.Threading;
    using System.Threading.Tasks;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Queries;
    using UserManagement.Application.User.VM;
    using UserManagement.Domain.UnitOfWork;
    using Xunit;

    [Collection("UserCollection")]
    public class GetSingleUserQueryTest
    {
        private readonly IConfigConstants constant;
        private readonly IMapper mapper;
        private readonly IUnitOfWork unitOfWork;

        public GetSingleUserQueryTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
            mapper = userFixture.Mapper;
            unitOfWork = userFixture.UnitOfWork;
        }

        [Fact]
        public async Task Handle_ReturnsCorrectVM()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 110,
            };

            var handler = new GetSingleUserQuery.GetSingleUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(query, CancellationToken.None);
            result.ShouldBeOfType<UserVM>();
        }

        [Fact]
        public async Task Handle_ReturnCorrectAge_WhenDOBIsProvided()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 110,
            };

            var handler = new GetSingleUserQuery.GetSingleUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(query, CancellationToken.None);
            result.UserList[0].Age.ShouldBe(21);
        }

        [Fact]
        public async Task Handle_ReturnCorrectsalutation_WhenGenderIsProvided()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 100,
            };

            var handler = new GetSingleUserQuery.GetSingleUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(query, CancellationToken.None);
            result.UserList[0].Salutation.ShouldContain("Sir");
        }
    }
}

The above-given tests are specific to GetSingleUserQuery class tests where we are testing the returned VM is of UserVM in the first test, verifying age if we are sending user with UserID as 110 in the second test, correct salutation in the third test. Remember the users are returned by GetUserList() in the UserFixture class and not from the actual database, so write your test cases accordingly. Go ahead and write a few more tests you think can be helpful to thoroughly test the GetSingleUserQuery class.

In the UserManagement.Application project, you can see we have a separate validator class for GetSingleUserQuery in User -> Queries folder using fluent validation. Let’s write the test cases to verify all the validation rules. Create a new class GetSingleUserQueryValidatorTest next to GetSingleUserQueryTest class and replace its content with the following code:

namespace UserManagement.ApplicationTests.User.Queries
{
    using Shouldly;
    using System.Linq;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Queries;
    using Xunit;

    [Collection("UserCollection")]
    public class GetSingleUserQueryValidatorTest
    {
        private readonly IConfigConstants constant;

        public GetSingleUserQueryValidatorTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
        }

        [Fact]
        public void Validate_ReturnTrue_WhenAllDataIsValid()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 110,
            };

            var validator = new GetSingleUserQueryValidator(constant);
            var result = validator.Validate(query);
            result.IsValid.ShouldBeTrue();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenAllDataIsInValid()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 0,
            };

            var validator = new GetSingleUserQueryValidator(constant);
            var result = validator.Validate(query);
            result.IsValid.ShouldBeFalse();
        }

        [Fact]
        public void Validate_ReturnErrorMsg_WhenUserIDIsInValid()
        {
            var query = new GetSingleUserQuery
            {
                UserID = 0,
            };

            var validator = new GetSingleUserQueryValidator(constant);
            var result = validator.Validate(query);
            result.Errors.FirstOrDefault(x => x.ErrorMessage == constant.MSG_USER_NULLUSERID).ErrorMessage.ShouldBe(constant.MSG_USER_NULLUSERID);
            result.IsValid.ShouldBeFalse();
        }
    }
}

Before digging into the validator test class, first look into GetSingleUserQueryValidator in the Application project, you would see we have only one validation rule on UserID that it’s valued should be greater than zero otherwise return the error message. Now look into GetSingleUserQueryValidatorTest class, in the first test, we are creating the GetSingleUserQuery and passing the value of UserID, next we are an instance of GetSingleUserQueryValidator class and calling its method Validate() and passing GetSingleUserQuery class instance as a parameter. The Validate() function will return true or false based on the input value that we are verifying through ShouldBeTrue() function of Shouldy package.

In the second test, we are passing zero value to the UserID parameter and expecting falseresult from Validate() method. The third case is more interesting where we are also validating the error message returned by GetSingleUserQueryValidator class with our IConfigConstants values defined in the UserFixture class.

Now hopefully, we understood the basic building blocks of the Application project’s unit testing. The User commands tests are following the same principle as the above-explained User queries tests. Let’s create the user command and their corresponding validator tests.

User Commands Unit Tests

In User -> Commands folder, create following commands and commands validator test classes as follow:

namespace UserManagement.ApplicationTests.User.Commands
{
    using AutoMapper;
    using Shouldly;
    using System.Threading;
    using System.Threading.Tasks;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using UserManagement.Domain.UnitOfWork;
    using Xunit;

    [Collection("UserCollection")]
    public class AddUserCommandTest
    {
        private readonly IConfigConstants constant;
        private readonly IMapper mapper;
        private readonly IUnitOfWork unitOfWork;

        public AddUserCommandTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
            mapper = userFixture.Mapper;
            unitOfWork = userFixture.UnitOfWork;
        }

        [Fact]
        public async Task Handle_ReturnsCorrectVM()
        {
            var command = new AddUserCommand
            {
                FirstName = "John",
                LastName = "Doe",
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                DOB = new System.DateTime(1980, 01, 01),
                EmailAddress = "jdoe@fullstackhub.io",
                Gender = "M",
                PhoneNumber = "444-443-4444",
            };

            var handler = new AddUserCommand.AddNewUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBeOfType<int>();
        }

        [Fact]
        public async Task Handle_ReturnCorrectUserID_WhenSendCorrectPayload()
        {
            var command = new AddUserCommand
            {
                FirstName = "John",
                LastName = "Doe",
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                DOB = new System.DateTime(1980, 01, 01),
                EmailAddress = "jdoe@fullstackhub.io",
                Gender = "M",
                PhoneNumber = "444-443-4444",
            };

            var handler = new AddUserCommand.AddNewUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBe(100);
        }
    }
}
namespace UserManagement.ApplicationTests.User.Commands
{
    using Shouldly;
    using System.Linq;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using Xunit;

    [Collection("UserCollection")]
    public class AddUserCommandValidatorTest
    {
        private readonly IConfigConstants constant;

        public AddUserCommandValidatorTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
        }

        [Fact]
        public void Validate_ReturnTrue_WhenAllDataIsValid()
        {
            var command = new AddUserCommand
            {
                FirstName = "John",
                LastName = "Doe",
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                DOB = new System.DateTime(1980, 01, 01),
                EmailAddress = "jdoe@fullstackhub.io",
                Gender = "M",
                PhoneNumber = "444-443-4444",
            };

            var validator = new AddUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.IsValid.ShouldBeTrue();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenAllDataIsInValid()
        {
            var command = new AddUserCommand
            {
                FirstName = string.Empty,
                LastName = string.Empty,
                City = string.Empty,
                Country = string.Empty,
                State = string.Empty,
                Zip = null,
                EmailAddress = string.Empty,
                Gender = string.Empty,
                PhoneNumber = string.Empty,
            };

            var validator = new AddUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.IsValid.ShouldBeFalse();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenFirstNameIsEmpty()
        {
            var command = new AddUserCommand
            {
                FirstName = string.Empty,
                LastName = "Doe",
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                DOB = new System.DateTime(1980, 01, 01),
                EmailAddress = "jdoe@fullstackhub.io",
                Gender = "M",
                PhoneNumber = "444-443-4444",
            };

            var validator = new AddUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.Errors.FirstOrDefault(x => x.ErrorMessage == constant.MSG_USER_NULLFIRSTNAME).ErrorMessage.ShouldBe(constant.MSG_USER_NULLFIRSTNAME);
            result.IsValid.ShouldBeFalse();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenLastNameIsEmpty()
        {
            var command = new AddUserCommand
            {
                FirstName = "John",
                LastName = string.Empty,
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                DOB = new System.DateTime(1980, 01, 01),
                EmailAddress = "jdoe@fullstackhub.io",
                Gender = "M",
                PhoneNumber = "444-443-4444",
            };

            var validator = new AddUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.Errors.FirstOrDefault(x => x.ErrorMessage == constant.MSG_USER_NULLLASTNAME).ErrorMessage.ShouldBe(constant.MSG_USER_NULLLASTNAME);
            result.IsValid.ShouldBeFalse();
        }

    }
}
namespace UserManagement.ApplicationTests.User.Commands
{
    using AutoMapper;
    using Shouldly;
    using System.Threading;
    using System.Threading.Tasks;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using UserManagement.Domain.UnitOfWork;
    using Xunit;

    [Collection("UserCollection")]
    public class DeleteUserCommandTest
    {
        private readonly IConfigConstants constant;
        private readonly IMapper mapper;
        private readonly IUnitOfWork unitOfWork;

        public DeleteUserCommandTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
            mapper = userFixture.Mapper;
            unitOfWork = userFixture.UnitOfWork;
        }

        [Fact]
        public async Task Handle_ReturnsCorrectVM()
        {
            var command = new DeleteUserCommand
            {
                UserID = 100,
            };

            var handler = new DeleteUserCommand.DeleteUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBeOfType<bool>();
        }

        [Fact]
        public async Task Handle_ReturnTrue_WhenSendCorrectUserIDIsSent()
        {
            var command = new DeleteUserCommand
            {
                UserID = 100,
            };

            var handler = new DeleteUserCommand.DeleteUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBe(true);
        }
    }
}
namespace UserManagement.ApplicationTests.User.Commands
{
    using Shouldly;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using Xunit;

    [Collection("UserCollection")]
    public class DeleteUserCommandValidatorTest
    {
        private readonly IConfigConstants constant;

        public DeleteUserCommandValidatorTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
        }

        [Fact]
        public void Validate_ReturnTrue_WhenAllDataIsValid()
        {
            var command = new DeleteUserCommand
            {
                UserID = 100,
            };

            var validator = new DeleteUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.IsValid.ShouldBeTrue();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenAllDataIsInValid()
        {
            var command = new DeleteUserCommand
            {
                UserID = 0,
            };

            var validator = new DeleteUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.IsValid.ShouldBeFalse();
        }

    }
}
namespace UserManagement.ApplicationTests.User.Commands
{
    using AutoMapper;
    using Shouldly;
    using System.Threading;
    using System.Threading.Tasks;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using UserManagement.Domain.UnitOfWork;
    using Xunit;

    [Collection("UserCollection")]
    public class UpdateUserCommandTest
    {
        private readonly IConfigConstants constant;
        private readonly IMapper mapper;
        private readonly IUnitOfWork unitOfWork;

        public UpdateUserCommandTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
            mapper = userFixture.Mapper;
            unitOfWork = userFixture.UnitOfWork;
        }

        [Fact]
        public async Task Handle_ReturnsCorrectVM()
        {
            var command = new UpdateUserCommand
            {
                UserID = 100,
                City = "SpringField",
                Country = "USA",
                State = "VA",
                Zip = "66006",
                PhoneNumber = "888-88-8888",
            };

            var handler = new UpdateUserCommand.UpdateUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBeOfType<bool>();
        }

        [Fact]
        public async Task Handle_ReturnTrue_WhenSendCorrectPayloadIsSent()
        {
            var command = new UpdateUserCommand
            {
                UserID = 100,
                City = "SpringField",
                Country = "USA",
                State = "VA",
                Zip = "66006",
                PhoneNumber = "888-88-8888",
            };

            var handler = new UpdateUserCommand.UpdateUserHandler(constant, mapper, unitOfWork);
            var result = await handler.Handle(command, CancellationToken.None);
            result.ShouldBe(true);
        }
    }
}
namespace UserManagement.ApplicationTests.User.Commands
{
    using Shouldly;
    using System.Linq;
    using UserManagement.Application.Common.Interfaces;
    using UserManagement.Application.User.Commands;
    using Xunit;

    [Collection("UserCollection")]
    public class UpdateUserCommandValidatorTest
    {
        private readonly IConfigConstants constant;

        public UpdateUserCommandValidatorTest(UserFixture userFixture)
        {
            constant = userFixture.Constant;
        }

        [Fact]
        public void Validate_ReturnTrue_WhenAllDataIsValid()
        {
            var command = new UpdateUserCommand
            {
                UserID = 100,
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                PhoneNumber = "444-443-4444",
            };

            var validator = new UpdateUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.IsValid.ShouldBeTrue();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenAllDataIsInValid()
        {
            var command = new UpdateUserCommand{};

            var validator = new UpdateUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLUSERID)).ShouldNotBeNull();
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLPHNUM)).ShouldNotBeNull();
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLCITY)).ShouldNotBeNull();
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLSTATE)).ShouldNotBeNull();
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLCOUNTRY)).ShouldNotBeNull();
            result.IsValid.ShouldBeFalse();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenUserIDIsZero()
        {
            var command = new UpdateUserCommand
            {
                UserID = 0,
                City = "Falls Chruch",
                Country = "USA",
                State = "VA",
                Zip = "22044",
                PhoneNumber = "444-443-4444",
            };

            var validator = new UpdateUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLUSERID)).ShouldNotBeNull();
            result.IsValid.ShouldBeFalse();
        }

        [Fact]
        public void Validate_ReturnFalse_WhenStateIsNull()
        {
            var command = new UpdateUserCommand
            {
                UserID = 100,
                City = "Falls Chruch",
                Country = "USA",
                State = null,
                Zip = "22044",
                PhoneNumber = "444-443-4444",
            };

            var validator = new UpdateUserCommandValidator(constant);
            var result = validator.Validate(command);
            result.Errors.FirstOrDefault(e => e.ErrorMessage.Equals(constant.MSG_USER_NULLSTATE)).ShouldNotBeNull();
            result.IsValid.ShouldBeFalse();
        }
    }
}

In Visual Studio, select Test -> Run All Tests and make sure your all tests are green in Test Explorer. If Test Explorer is not visible on left side pane, get it from View -> Test Explorer. Feel free to add more tests or modify above one to see the response.

In next part, we will add write test cases for UserManagement.Persistence project to test the UserRepository functions.

Yaseer Mumtaz

One Reply to “ASP.NET Core with Angular Application Architecture – Part 9”

Leave a Reply

Your email address will not be published. Required fields are marked *