单元测试域对象

Jon*_*yMC 3 unit-testing domain-driven-design moq aggregateroot

当用户在活动页面上输入他们的电子邮件地址时,我们需要添加活动提醒.事件是另一个域对象.我们最初的想法是创建一个Customer域对象和相关的CustomerService:

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

我们如何在单元测试中验证确实在新客户上调用了AddEmailReminder方法?

我的想法:

  1. 使用工厂来创建客户.这闻起来是因为我认为你只应该使用工厂,而对象的创建有一些复杂性.
  2. 代码不好.也许有更好的方法来做到这一点?
  3. Moq魔术.

在一个单独的注释(也许它是相关的),我们如何决定这里的聚合根是什么?我们已经随意决定了客户,但它同样可以成为事件.我已阅读并理解有关聚合根的文章,但在此方案中尚不清楚.

Zor*_*art 6

在这种情况下,我会在创建客户的服务中创建一个受保护的方法,在测试中使用匿名内部类覆盖该方法,并使其返回一个模拟的Customer对象.然后,您可以在模拟Customer对象上验证是否已调用AddEmailReminder.就像是:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且在测试中(假设有限的C#知识,但它应该说明这一点):

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);
}
Run Code Online (Sandbox Code Playgroud)