【问题标题】:TDD behavior testing with no getters/setters没有 getter/setter 的 TDD 行为测试
【发布时间】:2012-04-09 13:33:57
【问题描述】:

我正在将 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 时,我该怎么做。我可以添加一种方法来检索特定索引处的组,但这种破坏性封装不是为了可测试吗?

解决这个问题的正确方法是什么?

编辑

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

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

【问题讨论】:

    标签: unit-testing tdd cqrs event-sourcing


    【解决方案1】:

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

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

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

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

    你能在较低的级别上测试吗?

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

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

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

    如果您在上述任何一个级别都找不到合适的测试,那么您确定需要这个测试吗?如果没有可见的外部差异,则无需通过测试将行为锁定到位。

    【讨论】:

    • 有趣。目前排序对我可以看到的后续命令没有影响。这只是用户为了优先考虑而做出的审美改变。我的更新、删除、编辑命令不会投射任何我可以测试的状态,所以我不能使用这些方法。重新进行较低级别的测试,AR 上的 handle 方法实际上是重新排序的,我仍然看不到在当前实现中如何在较低级别进行测试。
    • @madcapnmckay 如果组没有重新排序,您的应用程序会出现什么问题?
    • 目前我什么都猜不到。我明白你在说什么,如果没有任何问题,我们为什么需要测试。如果有什么东西坏了,我可以在休息时针对测试。
    • @madcapnmckay 是的。也许如果您连续两次重新排序,那么第二次会引发包含错误信息的事件?
    猜你喜欢
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多