Pruebas Unitarias | Explicación completa: C# y .NET
Tags: unittest, programming, csharp, dotnet
Published: 2023-05-05 01:19:55

## Introducción

Hola buenas, mi nombre es Daniela Barazarte y te quiero dar la bienvenida a esta explicación completa de las pruebas unitarias en ambiente de C# y .NET. Te voy a enseñar lo que necesitas saber, y también lo que necesitas practicar.

Si prefieres los videos, aquí tienes un tutorial completo sobre este tema en YouTube: https://www.youtube.com/watch?v=znzcpBjNqK0

## <u>Teoría</u>
### Lógica
"Prueba Unitaria"
- **Prueba**: acción de probar alguien o algo para conocer sus cualidades, verificar su eficacia, saber cómo funciona o reacciona, o qué resultado produce
- **Unitaria**: que está formado por una sola unidad

Tomando en cuenta la definición de las palabras por separado, tendrás una mayor idea de que significa

### Definición
Las **pruebas unitarias** son las pruebas que utilizamos para probar/testear partes pequeñas de un sistema de software, como por ejemplo, probar/testear métodos.

### Uso
![Ejemplo en dibujo del](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eokeqhu4mjv5r24wpy50.png)

Si yo quisiera probar una pequeña parte de todo este proyecto, tendría que correr toda la solución para poder probarla... pero con las pruebas unitarias puedo probar solo la unidad/parte que necesito

## <u>Práctica</u>
### Ejercicio
Tienes una aplicación web API que tiene métodos para crear, leer, editar y eliminar los tickets de una estación de trenes, la tarea sería de que debes probar que todos los métodos funcionen correctamente.

Hay dos métodos para resolver la tarea:

1. Correr toda la solución y probar cada método de manera individual
2. Utilizar las pruebas unitarias, crear un script y correrlo todo de manera automática


**<u>Método: pruebas manuales
</u>**
1. Corro toda la solución
2. Abro mi servidor local (localhost)
3. Voy probando cada uno de los métodos de manera manual
4. Compruebo que funciona
5. Finalizo el servidor local

Si quiero hacer la prueba otra vez debo repetir el mismo proceso, una y otra vez.

**<u>Método: pruebas unitarias</u>**
1. Creo mi proyecto de pruebas unitarias (Add Project > Nunit Test Project)

![Nunit Test Project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7xc9z6ipk4rsps03vpc.png)
También será importante instalar 3 paquetes Nugets (todos con la misma versión):
- Microsoft.AspNetCore
- Microsoft.AspNetCore.TestHost
- Microsoft.EntityFrameworkCore.InMemory

2. Agrego el archivo importante de "Startup"

```
public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            // Configura contexto de la base de datos
            services.AddDbContext<TicketMicroserviceContext>(options => options.UseInMemoryDatabase("TicketMicroserviceTest"));

            // Agrega los transient de los AppServices que vas a utilizar
            services.AddTransient<ITicketsAppService, TicketsAppService>();
            services.AddTransient<IRepository<int, Ticket>, Repository<int, Ticket>>();
        }
        public void Configure()
        {
        }
```
3. Agrego el archivo de las pruebas y coloco todo el script
```
public class TicketsTest
    {
        protected TestServer server;

        // Agregar una instancia para el servidor del test
        [OneTimeSetUp]
        public void Setup()
        {
            this.server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
        }

        [Order(1)]
        [Test]
        public async Task InsertTicket_Test()
        {
            var _ticketAppService = server.Host.Services.GetService<ITicketsAppService>();

            var addTicket1 = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 1, JourneyId = 1, Seat = 1 });
            var getTicket1 = await _ticketAppService.GetTicketAsync(addTicket1.Id);

            Assert.IsNotNull(addTicket1);
            Assert.AreEqual(addTicket1.PassengerId, getTicket1.PassengerId);
            Assert.AreEqual(addTicket1.JourneyId, getTicket1.JourneyId);
            Assert.AreEqual(addTicket1.Seat, getTicket1.Seat);


            var addTicket2 = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 2, JourneyId = 2, Seat = 2 });
            var getTicket2 = await _ticketAppService.GetTicketAsync(addTicket2.Id);

            Assert.IsNotNull(addTicket2);
            Assert.AreEqual(addTicket2.PassengerId, getTicket2.PassengerId);
            Assert.AreEqual(addTicket2.JourneyId, getTicket2.JourneyId);
            Assert.AreEqual(addTicket2.Seat, getTicket2.Seat);

        }
        [Order(2)]
        [Test]
        public async Task GetAllTickets_Test()
        {
            var _ticketAppService = server.Host.Services.GetService<ITicketsAppService>();

            var insertFirst = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 1, JourneyId = 1, Seat = 1 });
            var insertSecond = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 2, JourneyId = 2, Seat = 2 });
            var insertThird = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 3, JourneyId = 3, Seat = 3 });

            var list = await _ticketAppService.GetTicketsAsync();

            Assert.IsNotNull(list);
            Assert.AreEqual(list.Count, 3);
        }
        [Order(3)]
        [Test]
        public async Task EditTicket_Test()
        {
            var _ticketAppService = server.Host.Services.GetService<ITicketsAppService>();

            var originalTicket = new TicketDTO() { PassengerId = 1, JourneyId = 1, Seat = 1 };
            var insertEntity = await _ticketAppService.InsertTicketAsync(originalTicket);

            var editedTicket = new Ticket() { Id = insertEntity.Id, PassengerId = 2, JourneyId = 2, Seat = 2 };
            var updateEntity = await _ticketAppService.EditTicketAsync(editedTicket);

            var checkUpdate = await _ticketAppService.GetTicketAsync(insertEntity.Id);

            Assert.IsNotNull(originalTicket);
            Assert.AreNotEqual(originalTicket.PassengerId, checkUpdate.PassengerId);
            Assert.AreNotEqual(originalTicket.JourneyId, checkUpdate.JourneyId);
            Assert.AreNotEqual(originalTicket.Seat, checkUpdate.Seat);
        }
        [Order(4)]
        [Test]
        public async Task DeleteTicket_Test()
        {
            var _ticketAppService = server.Host.Services.GetService<ITicketsAppService>();

            var addTicket = await _ticketAppService.InsertTicketAsync(new TicketDTO() { PassengerId = 1, JourneyId = 1, Seat = 1 });

            await _ticketAppService.DeleteTicketAsync(addTicket.Id);
            var checkDelete = await _ticketAppService.GetTicketAsync(addTicket.Id);

            Assert.IsNull(checkDelete);
        }
```
4. Corro el script completo

Quizá me he tardado más creando el proyecto de pruebas unitarias desde cero, pero si quiero probar el script varias veces más será más fácil y más rápido

## Conclusión

**Las pruebas unitarias:**
- Mejoran la calidad del software
- Reducen el tiempo de desarrollo
- Hacen la depuración mucho más sencilla
- Dan mayor confianza al código

## Agradecimiento

Muchas gracias por leer, si tienes alguna duda puedes comentar, también me puedes encontrar en mis otras redes como [Twitter](https://twitter.com/elabarazarte), [GitHub ](https://github.com/danielabarazarte) y [LinkedIn](https://www.linkedin.com/in/danielabarazarteg/)