Frage

Wir haben eine Anforderung eine Terminerinnerung hinzufügen, wenn ein Benutzer auf einer Event-Seite ihre E-Mail-Adresse eingibt. Ereignis ist ein weiteres Domain-Objekt. Unser erster Gedanke war, einen Kunde Domain-Objekt und damit verbundenen Customerservice zu erstellen:

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

Wie können wir in einem Unit-Test überprüfen, ob die AddEmailReminder Methode in der Tat auf den neuen Kunden genannt wurde?

Meine Gedanken:

  1. eine Fabrik Verwenden Sie den Kunden zu schaffen. Das riecht, weil ich dachte, dass Sie nur sollten Fabrik verwendet werden, wo eine gewisse Komplexität in der Objekterstellung war.
  2. Bad Code. Vielleicht gibt es einen besseren Weg, dies zu tun?
  3. Moq Magie.

Auf einem separaten Notiz (vielleicht ist es im Zusammenhang), wie entscheiden wir, welche das Aggregat Wurzel ist hier? Wir haben beschlossen, willkürlich der Kunde ist, aber es könnte ebenso das Ereignis sein. Ich habe gelesen und verstanden Artikel auf aggregierten Wurzeln, aber es ist in diesem Szenario unklar.

War es hilfreich?

Lösung

In Fällen wie diesem I eine geschützte Methode in den Dienst schaffen würde, die den Kunden erstellt, in dem Test überschreiben diese Methode es mit anonymen inneren Klasse, und machen es zu einem Mock-Customer-Objekt zurück. Dann können Sie auf dem Mock-Customer-Objekt überprüfen, ob AddEmailReminder aufgerufen wurde. So etwas wie:

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

und im Test (unter der Annahme begrenzt C # Wissen, aber es sollte den Punkt illustrieren):

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

Andere Tipps

Gedanken über die Customer API

Gibt es besondere Gründe, warum Sie sich entschieden haben, diesen Vorgang in einem Customer zu verkapseln? Das sieht ein wenig Anemic zu mir. Könnte es möglicherweise stattdessen direkt auf den Kunden eingekapselt werden?

Vielleicht verlassen Sie etwas von dem Customercodeb. aus, Dinge zu vereinfachen ...

Wenn Sie jedoch muß die Unterschrift Ändern eines Kunden Instanz nehmen löst das Problem:

public void AddEventReminder(Customer customer, int eventId)

aber dann wieder, ein Int32 qualifiziert kaum als Domain-Objekt, so dass die Unterschrift wirklich sein sollte

public void AddEventReminder(Customer customer, Event event)

Die Frage ist nun, ob diese Methode überhaupt Wert hinzufügt?

Welches ist das Aggregat Wurzel ist?

Keiner von ihnen würde ich denken. Ein Aggregat Wurzel zeigt an, dass Sie Kinder nur durch die Wurzel zu verwalten, und das wäre nicht sinnvoll, so oder so in diesem Fall machen.

Beachten Sie die Optionen:

Wenn Sie Ereignis der Wurzel zu machen, würde es bedeuten, dass Sie keine CustomerRepository haben könnte, und der einzige Weg, können Sie abrufen, bearbeiten und beharren würde ein Kunde durch ein Ereignis sein. Das klingt sehr falsch zu mir.

Wenn Sie Kunde die Wurzel zu machen, können Sie keine EventRepository haben, und der einzige Weg, können Sie abrufen, bearbeiten und bleiben ein Ereignis durch einen bestimmten Kunden sein würde. Das klingt für mich genauso falsch.

Die einzige verbleibende Möglichkeit ist, dass sie getrennte Wurzeln sind. Das bedeutet auch, dass sie nur lose miteinander verbunden sind, und dass Sie irgendeine Art von Domain-Service benötigen Events für einen Kunden zu suchen, oder Kunden, für ein Ereignis.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top