C# – Unit test with Moq

In this post, we will see how to use Moq in order to create Unit Test for a Class Library project used
to manage CRUD operations.
But, what is Moq?
Moq is a library used to create mock objects that simulate or mimic a real object.
Here, we can find the Moq project.


First of all, we define the User entity:

[User.cs]

using System;

namespace Domain.Entities
{
    public class User
    {
        public Guid Id { get; set; }
        public string UserName { get; set; }
    }
}


Then, we define the Interface used to define the repository:

[IUserRepository.cs]

using Domain.Entities;
using System;
using System.Collections.Generic;

namespace Domain.DataAccess.Interfaces
{
    public interface IUserRepository
    {
        List<User> GetAll();
        User GetById(Guid id);
        bool Add(User user);
        bool Delete(Guid id);
        bool Update(User user);
    }
}


Finally, we define the class UserCore used to manage the CRUD operations:

[UserCore.cs]

using Domain.DataAccess.Interfaces;
using Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Domain.Command
{
    public class UserCore
    {
        private readonly IUserRepository _userRepository;
        public UserCore(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        public List<User> GetAllUsers(out string message)
        {
            message = string.Empty;
            List<User> lstUsers = null;

            try
            {
                lstUsers = _userRepository.GetAll();
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return lstUsers;
        }

        public User GetUserById(Guid id, out string message)
        {
            message = string.Empty;
            User user = null;

            try
            {
                user = _userRepository.GetById(id);
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return user;
        }

        public bool AddUser(User user, out string message)
        {
            message = string.Empty;
            bool result = false;
            User checkUser = _userRepository.GetAll().Where(x => x.UserName == user.UserName).FirstOrDefault();

            if(checkUser!=null)
            {
                message = "UserName already exists!";
                return result;
            }

            try
            {
                result = _userRepository.Add(user);
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return result;
        }

        public bool UpdateUser(User user, out string message)
        {
            message = string.Empty;
            bool result = false;
            User checkUser = _userRepository.GetAll().Where(x => x.UserName == user.UserName && x.Id!=user.Id).FirstOrDefault();

            if (checkUser != null)
            {
                message = "UserName already exists!";
                return result;
            }

            try
            {
                result = _userRepository.Update(user);
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return result;
        }

        public bool DeleteUser(Guid id, out string message)
        {
            message = string.Empty;
            bool result = false;
            User checkUser = _userRepository.GetById(id);

            if (checkUser == null)
            {
                message = "User not exists!";
                return result;
            }

            try
            {
                result = _userRepository.Delete(id);
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return result;
        }
    }
}


We have finished to create our Class Library and now, we add a UnitTest project where we will add the library Moq.

Finally, we define the class UnitTest_UserCore where we will create all the tests:

[UnitTest_UserCore.cs]

using Domain.Command;
using Domain.DataAccess.Interfaces;
using Domain.Entities;
using Moq;
using System;
using System.Collections.Generic;
using Xunit;

namespace UnitTest
{
    public class UnitTest_UserCore
    {
        private readonly Mock<IUserRepository> userRepository;
        private readonly UserCore objUserCore;

        public UnitTest_UserCore()
        {
            userRepository = new Mock<IUserRepository>();
            objUserCore = new UserCore(userRepository.Object);
        }

        [Fact]
        public void GetAllUsers_ShouldReturnListOfUser()
        {
            // Arrange

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName=  "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);

            // Act
            // run the method
            var result = objUserCore.GetAllUsers(out string message);

            // Assert
            Assert.Equal(lstUsers.Count, result.Count);
            Assert.Empty(message);
        }

        [Fact]
        public void GetAllUsers_WithAnException_ShouldReturnAnErrorMessage()
        {
            // Arrange

            // we define an exception when we call GetAll method
            userRepository.Setup(setup => setup.GetAll()).Throws(new Exception());

            // Act
            // run the method
            var result = objUserCore.GetAllUsers(out string message);

            // Assert
            Assert.Null(result);
            Assert.NotEmpty(message);
        }


        [Fact]
        public void GetUserById_ShouldReturnAnUser()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            // we create the moq for the method GetById 
            // 1) we define the output
            User objUsers = new User { Id = idUser, UserName = "UserName_10" };
            // 2) we define objUsers as the output of GetById method
            userRepository.Setup(setup => setup.GetById(idUser)).Returns(objUsers);

            // Act
            // run the method
            var result = objUserCore.GetUserById(idUser, out string message);

            // Assert
            Assert.NotNull(result);
            Assert.Equal(idUser, result.Id);
            Assert.Empty(message);
        }

        [Fact]
        public void GetUserById_WithAnException_ShouldReturnErrorMessage()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            // we define an exception when we call GetById method
            userRepository.Setup(setup => setup.GetById(idUser)).Throws(new Exception());

            // Act
            // run the method
            var result = objUserCore.GetUserById(idUser, out string message);

            // Assert
            Assert.Null(result);
            Assert.NotEmpty(message);
        }


        [Fact]
        public void AddUser_ShouldReturnTrue()
        {
            // Arrange
            User objUsers = new User { UserName = "UserName_10" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);
            // 3) we define the output for the method Add
            userRepository.Setup(setup => setup.Add(objUsers)).Returns(true);

            // Act
            // run the method
            var result = objUserCore.AddUser(objUsers, out string message);

            // Assert
            Assert.True(result);
            Assert.Empty(message);
        }

        [Fact]
        public void AddUser_WithTheUserNameAlreadyPresent_ShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            User objUsers = new User { UserName = "UserName_2" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);

            // Act
            // run the method
            var result = objUserCore.AddUser(objUsers, out string message);

            // Assert
            Assert.False(result);
            Assert.Equal("UserName already exists!", message);
        }

        [Fact]
        public void AddUser_WithAnException_ShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            User objUsers = new User { UserName = "UserName_10" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);
            // 3) we define the output for the method Add
            userRepository.Setup(setup => setup.Add(objUsers)).Throws(new Exception());

            // Act
            // run the method
            var result = objUserCore.AddUser(objUsers, out string message);

            // Assert
            Assert.False(result);
            Assert.NotEmpty(message);
        }


        [Fact]
        public void UpdateUser_ShouldReturnTrue()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            User objUsers = new User { Id= idUser,  UserName = "UserName_10" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = idUser, UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);
            // 3) we define the output for the method Update
            userRepository.Setup(setup => setup.Update(objUsers)).Returns(true);

            // Act
            // run the method
            var result = objUserCore.UpdateUser(objUsers, out string message);

            // Assert
            Assert.True(result);
            Assert.Empty(message);
        }

        [Fact]
        public void UpdateUser_WithTheUserNameAlreadyPresent_ShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            User objUsers = new User { Id = idUser, UserName = "UserName_1" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = idUser, UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);

            // Act
            // run the method
            var result = objUserCore.UpdateUser(objUsers, out string message);

            // Assert
            Assert.False(result);
            Assert.Equal("UserName already exists!", message);
        }

        [Fact]
        public void UpdateUser_WithAnException_ShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            User objUsers = new User { Id = idUser, UserName = "UserName_10" };

            // we create the moq for the method GetAll 
            // 1) we define the output
            List<User> lstUsers = new List<User>();
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_1" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_2" });
            lstUsers.Add(new User { Id = idUser, UserName = "UserName_3" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_4" });
            lstUsers.Add(new User { Id = Guid.NewGuid(), UserName = "UserName_5" });
            // 2) we define lstUser as the output of GetAll method
            userRepository.Setup(setup => setup.GetAll()).Returns(lstUsers);
            // 3) we define the output for the method Update
            userRepository.Setup(setup => setup.Update(objUsers)).Throws(new Exception());

            // Act
            // run the method
            var result = objUserCore.UpdateUser(objUsers, out string message);

            // Assert
            Assert.False(result);
            Assert.NotEmpty(message);
        }


        [Fact]
        public void DeleteUser_ShouldReturnTrue()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            // we create the moq for the method GetById 
            // 1) we define the output
            User objUsers = new User { Id = idUser, UserName = "UserName_1" };
            // 2) we define objUsers as the output of GetById method
            userRepository.Setup(setup => setup.GetById(idUser)).Returns(objUsers);
            // 3) we define the output for the method Delete
            userRepository.Setup(setup => setup.Delete(idUser)).Returns(true);

            // Act
            // run the method
            var result = objUserCore.DeleteUser(idUser, out string message);

            // Assert
            Assert.True(result);
            Assert.Empty(message);
        }

        [Fact]
        public void DeleteUser_WithAWrongIdUserShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            // we create the moq for the method GetById 
            // 1) we define the output
            User objUsers =  null;
            // 2) we define objUsers as the output of GetById method
            userRepository.Setup(setup => setup.GetById(idUser)).Returns(objUsers);

            // Act
            // run the method
            var result = objUserCore.DeleteUser(idUser, out string message);

            // Assert
            Assert.False(result);
            Assert.Equal("User not exists!", message);
        }

        [Fact]
        public void DeleteUser_WithAnException_ShouldReturnFalseWithErrorMessage()
        {
            // Arrange
            Guid idUser = Guid.NewGuid();

            // we create the moq for the method GetById 
            // 1) we define the output
            User objUsers = new User { Id = idUser, UserName = "UserName_1" };
            // 2) we define objUsers as the output of GetById method
            userRepository.Setup(setup => setup.GetById(idUser)).Returns(objUsers);
            // 3) we define the output for the method Delete
            userRepository.Setup(setup => setup.Delete(idUser)).Throws(new Exception());

            // Act
            // run the method
            var result = objUserCore.DeleteUser(idUser, out string message);

            // Assert
            Assert.False(result);
            Assert.NotEmpty(message);
        }
    }
}


We have done and now we can run the test: