Pergunta

Nós temos um requisito para adicionar um lembrete de evento quando um usuário digita seu endereço de e-mail em uma página do evento. Evento é outro objeto de domínio. Nosso pensamento inicial era criar um objeto de domínio do cliente e CustomerService relacionada:

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

Como podemos verificar em um teste de unidade que o método AddEmailReminder estava realmente pediu que o novo cliente?

Os meus pensamentos:

  1. Use uma fábrica para criar o cliente. Isso cheira porque achei que você só deve uso da fábrica onde havia alguma complexidade na criação do objeto.
  2. código de Bad. Talvez haja uma maneira melhor de fazer isso?
  3. Moq magia.

Em uma nota separada (talvez ela está relacionada), como é que vamos decidir qual é a raiz agregada aqui? Decidimos arbitrariamente o cliente é, mas poderia igualmente ser o evento. Eu li e compreender artigos sobre raízes agregado, mas não está claro neste cenário.

Foi útil?

Solução

Em casos como este eu iria criar um método protegido no serviço que cria o cliente, na substituição de teste que método lo com classe interna anônima, e fazê-lo retornar um objeto Cliente simulada. Então você pode verificar no objeto Cliente simulada que AddEmailReminder foi chamado. 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);
    }
}

e no teste (assumir conhecimento limitado C #, mas deve ilustrar o ponto):

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

Outras dicas

Reflexões sobre a API CustomerService

Existem motivos especiais para que você decidiu para encapsular esta operação em um CustomerService? Este parece um pouco Anemic para mim. Poderia, eventualmente, ser encapsulada diretamente no cliente em vez disso?

Talvez você deixou de fora algo do exemplo de código CustomerService para simplificar as coisas ...

No entanto, se for necessário, alterar a assinatura de tomar uma instância cliente resolve o problema:

public void AddEventReminder(Customer customer, int eventId)

Mas, novamente, um Int32 dificilmente se qualifica como objeto de domínio, de modo a assinatura deve ser realmente

public void AddEventReminder(Customer customer, Event event)

A questão agora é se este método adiciona qualquer valor em tudo?

Qual é a raiz agregada?

Nenhum deles, eu acho. Uma raiz agregada indica que você gerenciar crianças única através da raiz, e que não faria sentido qualquer forma, neste caso.

Considere as opções:

Se você fizer Evento raiz, isso significaria que você não poderia ter CustomerRepository, ea única maneira que você poderia recuperar, editar e persistir um cliente seria através de um evento. Isso soa muito errado para mim.

Se você fazer o cliente a raiz, você não pode ter EventRepository, ea única maneira que você poderia recuperar, editar e persistir um evento seria através de um determinado cliente. Isso soa tão errado para mim.

A possibilidade que resta é que eles são raízes separadas. Isto também significa que eles são apenas vagamente conectados uns aos outros, e que você vai precisar de algum tipo de serviço de domínio para procurar eventos para um cliente, ou clientes para um evento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top