es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo hacer pruebas unitarias adecuadas para raíces de agregado?

Tomemos el siguiente ejemplo:

    internal class Meeting
    {
        public int Id { get; set; }
    }

    internal class DailyRoomReservation
    {
        private ISet<Meeting> _meetings { get; set; } = new HashSet<Meeting>();

        internal void ScheduleMeeting(Meeting meeting)
        {
            if (_meetings.Contains(meeting)) throw new InvalidOperationException();
            _meetings.Add(meeting);
        }
    }

Suponiendo que DailyRoomReservation es mi agregado raíz (omití intencionalmente la mayor parte de la lógica de negocio para simplificar), ¿cómo debo probar esto? Es una buena práctica exponer solo los métodos de comando para los agregados (terminología de CQS), especialmente cuando se utiliza CQRS a gran escala. Además, no tengo necesidad comercial de exponer la propiedad _meetings (por supuesto, probar su propósito no es una buena razón para hacerlo). Escribí las siguientes pruebas:

    [Test]
    internal void ScheduleNewMeeting_ShouldSucceed()
    {
        var uniqueMeeting = new Meeting() { Id = 1};
        var dailyRoomReservation = new DailyRoomReservation();
        dailyRoomReservation.ScheduleMeeting(uniqueMeeting);
    }

    [Test]
    internal void ScheduleSameMeetingTwice_ShouldFail()
    {
        var meeting = new Meeting() { Id = 1};
        var dailyRoomReservation = new DailyRoomReservation();
        dailyRoomReservation.ScheduleMeeting(meeting);

        Action scheduleMeeting = () => dailyRoomReservation.ScheduleMeeting(meeting);
        scheduleMeeting.Should().ThrowExactly<InvalidOperationException>();
    }

Y funcionan bastante bien, sin embargo, todavía no puedo validar en ese punto si la reunión se ha agregado realmente. ¿Cómo puedo mejorar mi enfoque?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una opción para refinar el enfoque sería agregar una prueba que verifique si la reunión se ha agregado al conjunto _meetings después de llamar a ScheduleMeeting. Esto podría verse de la siguiente manera:

    [Test]
    internal void ScheduleNewMeeting_ShouldAddMeetingToMeetingsSet()
    {
        var uniqueMeeting = new Meeting() { Id = 1 };
        var dailyRoomReservation = new DailyRoomReservation();
    
        dailyRoomReservation.ScheduleMeeting(uniqueMeeting);
    
        dailyRoomReservation.Meetings.Should().Contain(uniqueMeeting);
    }
    

    Esta prueba crea una nueva reunión y una nueva instancia de DailyRoomReservation. Luego programa la reunión y verifica si la reunión se ha agregado al conjunto _meetings llamando a la propiedad de solo lectura Meetings. Esta propiedad expone el conjunto _meetings pero no permite modificarlo desde el exterior, por lo que aún cumple con el principio de encapsulación del estado agregado. La prueba utiliza FluentAssertions para verificar si el conjunto contiene la reunión programada recientemente.

    Es importante tener en cuenta que esta prueba depende de los detalles de implementación interna de DailyRoomReservation, que pueden cambiar en el futuro sin afectar el comportamiento público del agregado. Por lo tanto, esta prueba no debe ser la única para este escenario y debe complementarse con pruebas que verifiquen las reglas de negocio y los invariantes del agregado.

Comments are closed.