应用 CQRS - 是否有必要对薄读取层进行单元测试?

发布于 2024-10-15 13:04:05 字数 333 浏览 6 评论 0原文

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

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

我对此事的想法:

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

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

非常感谢。

Given that some of the advice for implementing CQRS advocates fairly close-to-the-metal query implementation, such as ADO.NET queries directly against the database (or perhaps a LINQ-based ORM), is it a mistake to try and unit test them?

I wonder if it's really even necessary?

My thoughts on the matter:

  1. The additional architectural complexity to provide a mockable "Thin Read Layer" seems opposite to the very nature of the advice to keep the architectural ceremony to a minimum.
  2. The number of unit tests to effectively cover every angle of query that a user might compose is horrendous.

Specifically I'm trying CQRS out in an ASP.NET MVC application and am wondering whether to bother unit testing my controller action methods, or just test the Domain Model instead.

Many thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱情眠于流年 2024-10-22 13:04:05

我倾向于同意您的观点,即对此类代码进行单元测试并不是那么有益。但仍然有一些有用的测试的余地。

您必须对用户的读取查询参数执行一些验证,如果是这样,则测试无效的请求参数是否会引发适当的异常,并且允许使用有效的参数。

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

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

I would tend to agree with you that unit testing this kind of code is not so beneficial. But there is still some scope for some useful tests.

You must be performing some validation of the user's read query parameters, if so, then test that invalid request parameters throw a suitable exception, and valid parameters are allowed.

If you're using an ORM, I find the cost/benefit ratio too great for testing the mapping code. Assume your ORM is already tested, there could be errors in the mapping, but you'll soon find and fix them.

I also find it useful to write some Integration tests (using the same Testing framework), just to be sure I can make a connection to the database, and the ORM configuration doesn't throw any mapping exceptions. You certainly don't want to be writing unit tests that query the actual db.

柏林苍穹下 2024-10-22 13:04:05

根据我的经验,如果您正在创建一个很好的非规范化读取模型,那么您将执行的 90%-99% 的读取保证围绕它们进行单元测试。

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

In my experience 90%-99% of the reads you will be doing if you are creating a nice de-normalized read model DO NOT warrant having unit tests around them.

I have found that the most effective and efficient way to TDD a CQRS application is to write integration tests that push commands into your domain, then use the Queries to get the data back out of the DB for your assertions.

阳光①夏 2024-10-22 13:04:05

您可能已经知道,单元测试更多的是关于良好的设计,而不是代码覆盖率和防止错误。虽然我经常在匆忙时跳过测试读取模型事件处理程序,但毫无疑问,出于代码应该采用 TDD 的所有原因,可能应该这样做。

我也没有对我的 HTTP 操作进行单元测试(我本身没有控制器,因为我使用的是 Nancy 而不是 .NET MVC)。

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

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

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

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

As you probably already know unit testing is less about code coverage and preventing bugs than it is about good design. While I often skip testing the read-model event handlers when I'm in a hurry, there can be no doubt that it probably should be done for all the reasons code should be TDD'd.

I also have not be unit testing my HTTP actions (I don't have controllers per se since I'm using Nancy not .NET MVC).

These are integration points and don't tend to contain much logic since most of it is encapsulated in the command handlers and domain model.

The reason I think it is fairly easy not to test these is because they are very simple and very repetitive, there is almost no deep thinking in the denormalization of events to the read-model. The same is true for my HTTP handlers, which pretty much just process the request and issue a command to the domain, with some basic logic for return a response to the client.

When developing, I often make mistakes in this code and I probably would make far fewer of these mistakes if I was using TDD, but it would also take much longer and these mistakes tend to be very easy to spot and fix.

My gut tells me I should still apply TDD here though, it is still all very loosely coupled and it shouldn't be hard to write the tests. If you are finding it hard to write the tests that could indicate a code smell in your controllers.

夏の忆 2024-10-22 13:04:05

我所看到的类似单元测试的方式是让单元测试在数据库中创建一组内容,运行单元测试,然后清除创建的内容。

在过去的一份工作中,我看到这种设置非常好,使用数据结构来描述对象及其关系。这是通过 ORM 运行来创建这些对象、这些对象以及用于查询的数据,然后使用 ORM 删除对象。为了使单元测试更容易设置每个类指定的默认值,以在不覆盖这些值的单元测试中使用。那么单元测试中的数据结构只需要指定非默认值,这使得单元测试的设置更加紧凑。

这些单元测试非常有用,并且发现了数据库交互中的许多错误。

The way that I have seen something like this unit tested is to have the unit test create a set of things in the database, you run your unit tests, then clean out the created things.

In one past job I saw this set up very nicely using a data structure to describe the objects and their relationships. This was run through the ORM to create those objects, with those relationships, data from that was used for the queries, and then the ORM was used to delete the objects. To make unit tests easier to set up every class specified default values to use in unit tests that didn't override those values. Then the data structure in the unit tests only needed to specify non-default values, which made the setup of the unit tests much more compact.

These unit tests were very useful, and caught a number of bugs in the database interaction.

明天过后 2024-10-22 13:04:05

在我的一个 ASP.NET MVC 应用程序中,我还应用了 sqrc。但我们使用 文档数据库(mongodb) 代替 sql 和“ADO.NET 查询”或“Linq”,并且每个命令或事件处理程序直接更新数据库。

我已经为一个命令/事件处理程序创建了一个测试。经过 100% 的单元测试后,我知道我的域工作正确率达到 95%。
但对于 actions/controllers/ui 我已经应用了 ui 测试(使用 selenium)。

因此,域的单元测试(命令/事件处理程序和数据库的直接更新)和 ui 测试似乎都是您的“集成测试”。

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

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

In one my asp.net mvc application i've also applied sqrc. But instead of sql and 'ADO.NET queries' or 'Linq' we using document database(mongodb) and each command or event handler direct update database.

And i've created one test for one command/event handler. And after 100% unit testing i know that my domain work on 95% correct.
But for actions/controllers/ui i've applied ui tests(using selenium).

So seems both unit tests for the domain(commands/events handlers and direct updates to database) and ui tests it your 'integration tests'.

I think that you should test domain part at least, because all your logic incapsulated in command/event handlers.

FYI: I've also started developing domain part first from entity framework, than direct updates into database through stored procedures but was really happy with document database. I tried some different document databases but mongodb looks like best for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文