En este artículo veremos cómo podemos realizar pruebas unitarias en net core, para este pequeño ejemplo cree un proyecto web api en net core 6 pero es aplicable a versiones anteriores, al cual le realizaremos 2 pruebas unitarias una al controlador que te permite agregar un empleado y otra prueba al servicio que contiene la lógica para agregar el empleado a la base de datos.
Para realizar las pruebas unitarias creare un nuevo proyecto NUnit
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0.0
dotnet add package NSubstitute --version 4.2.2
El paquete Microsoft.EntityFrameworkCore.InMemory nos servira para poder usar EF con una base de datos en memoria, y NSubstitute como su nombre lo indica es como un sustituto(tipo mock) de datos. Antes empezar a escribir nuestra pruebas lo primero que debemos hacer es agregar como dependencia de proyectos el o los proyectos que estaremos usando.
Como realizaremos pruebas a nuestro controlador y a nuestro servicio crearemos 2 clases para realizar las respectivas pruebas(si son varias pruebas que vas a realizar que es lo mas comun, es buena práctica crear carpetas para cada tipo de pruebas).
Empecemos realizando las pruebas unitarias a nuestro controlador.
public class EmployeesControllerTest
{
private IEmployeeServices employeeServices;
private EmployeeRequest employeeRequest;
[SetUp]
public void SetUp()
{
employeeServices = Substitute.For<IEmployeeServices>();
employeeRequest = new EmployeeRequest()
{
Name = "Cristian",
Age = 30
};
}
[TestCase(HttpStatusCode.OK)]
[TestCase(HttpStatusCode.InternalServerError)]
public async Task When_Add_Employee_Controller(HttpStatusCode code)
{
//Arrange
GenericResponse response = new GenericResponse()
{
HttpCode = code
};
//Act
employeeServices.AddEmployee(employeeRequest).ReturnsForAnyArgs(response);
EmployeesController controller = new EmployeesController(employeeServices);
ObjectResult responseController = (ObjectResult)await controller.AddEmployee(employeeRequest);
//Assert
Assert.AreEqual((int)code, responseController.StatusCode.Value);
}
}
Para realizarle pruebas a nuestro controlador necesitamos 2 variables una que representa la interface del servicio que inyectamos en nuestro controlador y la otra variable que representa los parámetros que recibe nuestro método post, estas variables las inicializamos en el método SetUp que Nunit nos proporciona.En nuestro TestCase probamos la respuesta de nuestro controlador cuando la petición se realiza correctamente(devuelve un status code 200) y cuando sucede un error(devuelve status code 500).
Si observas estas pruebas se realizan siguiendo el patrón AAA que es de lo más usado al momento de escribir pruebas ya que te ayuda a que tu prueba sea fácil de leer y comprender.
Ahora realizaremos la prueba de nuestro servicio.
public class EmployeeServicesTest
{
private Employee employee;
private EmployeeRequest employeeRequest;
private IMapper mapper;
[SetUp]
public void Setup()
{
mapper = Substitute.For<IMapper>();
employee = new Employee()
{
Id = 1,
Name = "Cristian",
Age = 30
};
employeeRequest = new EmployeeRequest()
{
Name = "Cristian",
Age = 30
};
}
private IServiceProvider CreateContext(string nameDB)
{
var services = new ServiceCollection();
services.AddDbContext<EmployeeContext>(opt => opt.UseInMemoryDatabase(databaseName: nameDB),
ServiceLifetime.Scoped,
ServiceLifetime.Scoped);
return services.BuildServiceProvider();
}
[TestCase(HttpStatusCode.OK)]
[TestCase(HttpStatusCode.InternalServerError)]
public async Task When_Add_Employee_Services(HttpStatusCode code)
{
//Arrange
var nameDB = Guid.NewGuid().ToString();
var serviceProvider = CreateContext(nameDB);
var db = serviceProvider.GetService<EmployeeContext>();
db.Add(employee);
//Act
if (code == HttpStatusCode.OK)
mapper.Map<Employee>(employeeRequest).ReturnsForAnyArgs(employee);
else
mapper.Map<Employee>(employeeRequest).ThrowsForAnyArgs(x => { throw new Exception(); });
EmployeeServices services = new EmployeeServices(db, mapper);
var responseServices = await services.AddEmployee(employeeRequest);
//Assert
Assert.AreEqual(code, (responseServices.HttpCode));
}
}
Como en esta prueba vamos a simular la inserción de un registro usando ef usamos una base de datos en memoria, es por eso que creamos un método CreateContext que nos servirá para simular un contexto con ef de la bd que usaremos para nuestra prueba.En nuestro TestCase de igual manera probaremos el flujo cuando el registro se inserte correctamente en la base de datos y cuando este falle por alguna razón.
Si corremos nuestras pruebas veremos que estas se ejecutan correctamente.
puedes descargar el código desde este repositorio
Hasta la próxima.
Saludos desde El Salvador...
0 Comentarios