2

我正在将 TDD 应用于我的第一个以事件为中心的项目(CQRS、事件溯源等),并且我正在根据 Greg Young 的简单测试框架 Given、When、Expect 编写测试。我的测试夹具接受一个命令、命令处理程序和聚合根,然后测试输出的事件。

CommandTestFixture<TCommand, TCommandHandler, TAggregateRoot>

例如这里是一个典型的测试

[TestFixture]
public class When_moving_a_group : 
     CommandTestFixture<MoveGroup, MoveGroupHandler, Foo>

总的来说,我对这些测试非常满意,但是在上面的测试中我遇到了问题。聚合根包含一组组。该命令MoveGroup对集合进行重新排序,采用 from & to 索引。我设置了测试并断言GroupMoved使用正确的数据生成了正确的事件。

作为一项附加测试,我需要断言 Groups 集合的重新排序实际上是正确进行的?当聚合根没有公共 getter/setter 时,我该怎么做。我可以添加一种方法来检索特定索引处的组,但这种破坏性封装不是只是为了可测试吗?

这样做的正确方法是什么?

编辑

组的重新排序发生在 Aggregate 根上的 GroupMoved 处理程序中。

private void Apply(GroupMoved e)
{
    var moved = groups[e.From];
    groups.RemoveAt(e.From);
    groups.Insert(e.To, moved);
}
4

1 回答 1

1

这里的摩擦是因为你想要断言一些关于内部实现的东西,但你手头的东西是在顶层。

您的测试和断言需要处于相同的逻辑级别。有两种方法可以重新安排:

重新排序组对您在顶层拥有的后续命令或查询有什么影响?

这应该为您提供一种断言正确结果发生的途径,而无需直接断言有关组的顺序的任何事情。这使测试保持在顶层,并允许进行各种内部重构(例如,可能对组进行惰性排序)。

你能在较低的水平上测试吗?

如果您觉得上述测试过于复杂,您可能希望在更详细的级别上构建您的测试。我认为这就像专注于一个细节部分以使其正确。

在这个级别(而不是您的复合根),接口将了解组,您将有机会断言您想要断言的内容。

或者,你需要这个测试吗?

If you can not find a suitable test at either of the above levels, then are you sure you need this test at all? If there is no visible external difference then there is no need to lock the behaviour in place with a test.

于 2012-04-09T00:57:28.363 回答