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

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

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

我的想法:

  1. 使用工厂来创建客户。这闻起来很臭,因为我认为你只应该在对象创建有一定复杂性的地方使用工厂。
  2. 糟糕的代码。也许有更好的方法来做到这一点?
  3. 起订量魔法。

另请注意(也许是相关的),我们如何确定这里的聚合根?我们任意决定客户是,但它同样可以是事件。我已阅读并理解有关聚合根的文章,但在这种情况下尚不清楚。

有帮助吗?

解决方案

在这种情况下,我会在创建客户的服务中创建一个受保护的方法,在测试中使用匿名内部类覆盖该方法,并使其返回一个模拟 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);
    }
}

在测试中(假设 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);
}

其他提示

关于 CustomerService API 的思考

您决定将此操作封装在 CustomerService 中是否有任何特殊原因?这个看起来有点 贫血 大部头书。是否可以直接封装在客户上?

也许您遗漏了 CustomerService 代码示例中的一些内容来简化事情......

但是,如果必须,更改签名以采用 Customer 实例可以解决问题:

public void AddEventReminder(Customer customer, int eventId)

但话又说回来,Int32 几乎不符合域对象的资格,因此签名实际上应该是

public void AddEventReminder(Customer customer, Event event)

现在的问题是这种方法是否有任何价值?

哪个是聚合根?

我想他们都没有。聚合根表明您管理子项 仅有的 通过根,在这种情况下这两种方式都没有意义。

考虑以下选项:

如果您将事件作为根,则意味着您可能没有 CustomerRepository,并且检索、编辑和保留客户的唯一方法是通过事件。这对我来说听起来非常错误。

如果将 Customer 作为根,则可以没有 EventRepository,并且检索、编辑和保留事件的唯一方法是通过特定的 Customer。这对我来说同样是错误的。

唯一剩下的可能性是它们是单独的根。这也意味着它们彼此之间只是松散连接,并且您将需要某种领域服务来查找客户的事件或事件的客户。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top