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 create an UnitTest project where we will add the library Moq.
Finally, we define the class UnitTest_UserCore where we will create all 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: