Domanda

Abbiamo un obbligo di aggiungere un promemoria di un evento quando un utente inserisce il proprio indirizzo email in una pagina evento. Event è un altro oggetto di dominio. Il nostro pensiero iniziale era quello di creare un oggetto di dominio del cliente e relativo CustomerService:

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

Come possiamo verificare in una prova di unità che il metodo AddEmailReminder è stato effettivamente invitato il nuovo cliente?

I miei pensieri:

  1. Utilizzare una fabbrica per creare il cliente. Questo odore perché ho pensato che avrebbero dovuto utilizzare solo in fabbrica dove c'era una certa complessità nella creazione dell'oggetto.
  2. Codice Bad. Forse c'è un modo migliore per fare questo?
  3. magia Moq.

Una nota a parte (forse è legato), come decidiamo che è la radice di aggregazione qui? Abbiamo deciso arbitrariamente il cliente è, ma potrebbe ugualmente essere l'evento. Ho letto e compreso articoli su radici di aggregazione, ma non è chiaro in questo scenario.

È stato utile?

Soluzione

In casi come questo mi creerebbe un metodo protetto nel servizio che crea il cliente, nel test di ignorare che il metodo con classe interna anonima, e renderlo restituire un oggetto Customer finto. Poi si può verificare sul oggetto Customer finto che AddEmailReminder è stato chiamato. Qualcosa di simile:

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);
    }
}

e nel test (assumere limitata conoscenza di C #, ma dovrebbe illustrare il 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);
}

Altri suggerimenti

Pensieri sulla API CustomerService

Ci sono particolari motivi si è deciso di incapsulare questa operazione in un CustomerService? Questo sembra un po ' Anemic a me. Potrebbe eventualmente essere incapsulato direttamente sul cliente, invece?

Forse hai lasciato fuori qualcosa dell'esempio di codice CustomerService per semplificare le cose ...

Tuttavia, se è necessario, cambiare la firma di prendere un'istanza di Customer risolve il problema:

public void AddEventReminder(Customer customer, int eventId)

ma poi di nuovo, un Int32 difficilmente si qualifica come oggetto di dominio, quindi la firma in realtà dovrebbe essere

public void AddEventReminder(Customer customer, Event event)

La questione è ora se questo metodo aggiunge alcun valore a tutti?

che è la radice di aggregazione?

Nessuno di loro, penserei. Una radice di aggregazione indica che a gestire i bambini solo , attraverso la radice, e che non avrebbe senso in entrambi i casi, in questo caso.

Considerate le opzioni:

Se si effettua la radice Evento, vorrebbe dire che si potrebbe avere alcun CustomerRepository, e l'unico modo per recuperare, modificare e persistere un cliente sarebbe attraverso un evento. Che suona molto male per me.

Se si effettua la radice dei clienti, si può avere alcun EventRepository, e l'unico modo per recuperare, modificare e persistere un evento sarebbe attraverso uno specifico Cliente. Che suona altrettanto sbagliato per me.

La possibilità unica rimasta è che sono le radici distinte. Questo significa anche che sono solo vagamente collegati tra loro, e che sarà necessario un qualche tipo di servizio di dominio per cercare Eventi per un cliente o clienti per un evento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top