Pregunta

Tenemos el requisito de agregar un recordatorio de evento cuando un usuario ingresa su dirección de correo electrónico en una página de evento.El evento es otro objeto de dominio.Nuestra idea inicial fue crear un objeto de dominio Cliente y un Servicio de Cliente relacionado:

public class CustomerService {
    public void AddEventReminder(string emailAddress, int eventId) {
       var customer = new Customer(emailAddress);
       customer.AddEmailReminder(eventId);
    }
}

¿Cómo podemos verificar en una prueba unitaria que efectivamente se invocó el método AddEmailReminder en el nuevo cliente?

Mis pensamientos:

  1. Utilice una fábrica para crear el cliente.Esto huele mal porque pensé que se suponía que solo debías usar factory donde había cierta complejidad en la creación de objetos.
  2. Mal código.¿Quizás haya una mejor manera de hacer esto?
  3. Magia moq.

En una nota aparte (tal vez esté relacionado), ¿cómo decidimos cuál es la raíz agregada aquí?Hemos decidido arbitrariamente que el cliente lo es, pero también podría ser el evento.He leído y entiendo artículos sobre raíces agregadas, pero no está claro en este escenario.

¿Fue útil?

Solución

En casos como este, crearía un método protegido en el servicio que crea el cliente, en la prueba anularía ese método con una clase interna anónima y haría que devuelva un objeto Cliente simulado.Luego puede verificar en el objeto Cliente simulado que se llamó a AddEmailReminder.Algo como:

public class CustomerService {
    public void AddEventReminder(string emailAddress, int eventId) {
       var customer = createCustomer(emailAddress);
       customer.AddEmailReminder(eventId);
    }

    protected Customer createCustomer(string emailAddress) {
       return new Customer(emailAddress);
    }
}

y en la prueba (se supone un conocimiento limitado de C#, pero debería ilustrar el punto):

void testCustomerCreation() {
    /* final? */ Customer mockCustomer = new Customer("email");
    CustomerService customerService = new CustomerService() {
       protected Customer createCustomer(string emailAddress) {
           return mockCustomer;
       }            
    };

    customerService.AddEventReminder("email", 14);

    assertEquals(mockCustomer.EventReminder() /* ? */, 14);
}

Otros consejos

Reflexiones sobre la API a Cliente

¿Hay razones particulares por las que ha decidido encapsular esta operación en un CustomerService? Esto se ve un poco href="http://www.martinfowler.com/bliki/AnemicDomainModel.html" anémico para mí. ¿Sería posible encapsular directamente en el lugar de atención al cliente?

Tal vez lo dejó salir algo del ejemplo de código a Cliente para simplificar las cosas ...

Sin embargo, si es necesario, el cambio de la firma para tomar una instancia de cliente resuelve el problema:

public void AddEventReminder(Customer customer, int eventId)

pero por otra parte, un Int32 difícilmente califica como objeto de dominio, por lo que la firma debería ser

public void AddEventReminder(Customer customer, Event event)

La pregunta ahora es si este método añade ningún valor en absoluto?

¿Cuál es la raíz agregada?

Ninguno de ellos, yo pensaría. Una raíz agregada indica que la gestión de los niños solamente a través de la raíz, y que no tendría sentido de cualquier manera en este caso.

Tenga en cuenta las opciones:

Si realiza la raíz de sucesos, esto significaría que no puede usted tener CustomerRepository, y la única forma en que podría recuperar, editar y persistir un cliente sería a través de un evento. Eso suena muy mal a mí.

Si hace al cliente la raíz, que no puede tener EventRepository, y la única forma en que podría recuperar, editar y persistir un evento sería a través de un cliente específico. Eso suena tan mal a mí.

La única posibilidad restante es que son raíces independientes. Esto también significa que sólo se conectan entre ellas gracias a, y que se necesita algún tipo de servicio de Dominio para buscar eventos para un cliente o clientes para un evento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top