应用CQRS – 是否需要对薄读取层进行unit testing?

鉴于实现CQRS的一些建议提倡相当接近金属的查询实现,例如直接针对数据库(或者可能是基于LINQ的ORM)的ADO.NET查询,尝试unit testing是错误的他们?

我想知道它是否真的有必要吗?

我对此事的看法:

  1. 提供可模拟的“薄读取层”的额外架构复杂性似乎与将建筑仪式保持在最低限度的建议的本质相反。
  2. 有效覆盖用户可能构成的每个查询角度的unit testing数量是可怕的。

具体来说,我正在ASP.NET MVC应用程序中尝试CQRS,并且想知道是否打扰unit testing我的控制器操作方法,或者只是测试域模型。

提前谢谢了。

我倾向于同意你的观点,unit testing这种代码并不是那么有用。 但仍有一些有用的测试空间。

您必须对用户的读取查询参数执行某些validation,如果是,则测试无效请求参数是否引发了合适的exception,并且允许有效参数。

如果您使用的是ORM,我发现测试映射代码的成本/收益比太大了。 假设您的ORM已经过测试,映射中可能存在错误,但您很快就会发现并修复它们。

我还发现编写一些集成测试(使用相同的测试框架)很有用,只是为了确保我可以建立与数据库的连接,并且ORM配置不会抛出任何映射exception。 您当然不希望编写查询实际数据库的unit testing。

正如您可能已经知道的那样,unit testing不是关于代码覆盖率和防止错误,而是关于良好的设计。 虽然我在匆忙时经常跳过测试读模型事件处理程序,但毫无疑问,可能应该完成代码应该是TDD的所有原因。

我也没有对我的HTTP动作进行unit testing(因为我使用Nancy而不是.NET MVC,所以我没有控制器本身)。

这些是集成点,并且不会包含太多逻辑,因为大多数逻辑都封装在命令处理程序和域模型中。

我认为不容易测试这些的原因是因为它们非常简单且非常重复,对于读取模型的事件非规范化几乎没有深刻的思考。 对于我的HTTP处理程序也是如此,它几乎只是处理请求并向域发出命令,其中一些基本逻辑用于返回对客户端的响应。

在开发时,我经常在这段代码中犯错误,如果我使用TDD,我可能会减少这些错误,但这也需要更长的时间,这些错误往往很容易被发现和修复。

我的直觉告诉我,我仍然应该在这里应用TDD,它仍然是非常松散耦合的,并且编写测试应该不难。 如果您发现很难编写可能表明控制器中有代码味道的测试。

根据我的经验,如果你要创建一个漂亮的非规范化读取模型,你将要做的90%-99%的读取不要保证在它们周围进行unit testing。

我发现TDD CQRS应用程序最有效和最有效的方法是编写将命令推送到域中的集成测试,然后使用查询将数据从数据库中取回以用于断言。

我看到像测试这个单元的东西的方式是让unit testing在数据库中创建一组东西,运行unit testing,然后清理创建的东西。

在过去的一份工作中,我看到这个工作很好地使用数据结构来描述对象及其关系。 这是通过ORM运行来创建这些对象,使用这些关系,将来自该对象的数据用于查询,然后使用ORM删除对象。 为了使unit testing更容易设置每个类指定的默认值,以便在未覆盖这些值的unit testing中使用。 然后unit testing中的数据结构只需要指定非默认值,这使得unit testing的设置更加紧凑。

这些unit testing非常有用,并且在数据库交互中发现了许多错误。

在我的asp.net mvc应用程序中,我也应用了sqrc。 但是我们使用文档数据库(mongodb)和每个命令或事件处理程序直接更新数据库而不是sql和’ADO.NET查询’或’Linq’。

我为一个命令/事件处理程序创建了一个测试。 经过100%的unit testing后,我知道我的域名在95%上正常工作。 但是对于动作/控制器/我已经应用了ui测试(使用selenium )。

所以似乎域的unit testing(命令/事件处理程序和数据库的直接更新)和ui测试你的’集成测试’。

我认为你至少应该测试域部分,因为所有的逻辑都封装在命令/事件处理程序中。

仅供参考:我还开始从entity framework开始开发域部分,而不是通过存储过程直接更新到数据库,但对文档数据库非常满​​意。 我尝试了一些不同的文档数据库,但mongodb看起来对我来说最合适。