我正在将TDD应用于我的第一个以事件为中心的项目(CQRS,事件采购等),我正在根据Greg Young的简单测试框架Give,When,Expect编写我的测试。我的测试夹具接受命令,命令处理程序和聚合根,然后测试输出的事件。
CommandTestFixture<TCommand, TCommandHandler, TAggregateRoot>
例如,这是一个典型的测试
[TestFixture]
public class When_moving_a_group :
CommandTestFixture<MoveGroup, MoveGroupHandler, Foo>
我对这些测试总体上感到非常满意,但通过上述测试我遇到了问题。聚合根包含一组组。命令MoveGroup
重新排序集合,从&amp;索引。我设置了测试并声明使用正确的数据生成了正确的GroupMoved
事件。
作为一项额外的测试,我需要声明对Groups集合的重新排序实际上是否正确进行了?当聚合根没有公共getter / setter时,我该怎么做呢。我可以添加一个方法来检索特定索引处的组,但这不是简单的封装,只是为了可测试吗?
正确的方法是什么?
修改
组的重新排序发生在Aggregate root的GroupMoved处理程序中。
private void Apply(GroupMoved e)
{
var moved = groups[e.From];
groups.RemoveAt(e.From);
groups.Insert(e.To, moved);
}
答案 0 :(得分:1)
这里的摩擦是因为你想要对内部实现断言,但你手边的东西是最高级别。
您的测试和断言需要处于相同的逻辑级别。有两种方法可以重新安排:
重新订购群组对您在顶级群体中拥有的后续命令或查询有什么影响?
这应该为您提供一个断言正确结果的途径,而无需直接断言组的顺序。这使测试保持在顶层,并允许各种内部重构(例如,可能对组进行惰性排序)。
您可以在较低级别进行测试吗?
如果您认为上述测试过于复杂,您可能希望在更详细的级别上构建测试。我认为这就像专注于一部分细节才能做到正确。
在这个级别(而不是你的复合根),接口将知道组,你将有机会断言你想要断言的东西。
或者,您是否需要此测试?
如果您无法在上述任何一个级别找到合适的测试,那么您确定需要进行此测试吗?如果没有可见的外部差异,则无需使用测试锁定行为。