嘲笑一个实体?

ulu*_*ulu 2 tdd mocking

我听说某个地方嘲弄一个实体是个坏事,你应该只模拟服务(即使我们没有做全面的DDD,但是"sorta"DDD).

那么,鉴于以下典型故事,您如何为它编写测试?

  • 如果客户具有"首选"状态,则应在发生事件时通知她.

首选状态取决于其他因素,例如,客户最近购买了10个小部件,或者他的名字以"A"开头等.无论如何,我们假设我们已经实现了此功能.我如何为上述故事编写测试?具体来说,我对可测试性要求在这种情况下如何影响我的设计感兴趣.

  1. 我可以使用一些高级模拟框架(如Isolator),它允许我模拟非虚拟属性.可测性与设计之间没有相关性,没问题.
  2. 我可以将IsPreferred属性设置为虚拟并模拟它(实际上是stub).不知道为什么,但感觉很脏.请参阅帖子顶部的问题.此外,不知道它如何改善我的设计.2A.隐藏ICustomer接口后面的实体并模拟它.完全不酷.
  3. 我可以使它成为一个读写属性,但这将是一个非常糟糕的设计决定.

你是如何处理这些故事的?

Aug*_*sto 6

我在一些书/博客上读过类似的东西,建议不要模仿域模型中的实体或对象.据我记得的消息是不要模拟数据,模拟行为.(我可能在XUnit Test Patterns或GOOS一书中读过这篇文章).

就个人而言,我认为如果你的实体需要很多设置,那么模拟它是有效的.让我举个例子,假设你有品牌,产品,价格和StockAvailability.一个品牌有产品,产品有价格和库存.被测试类调用Brand.IsAvailable(),它反过来检查至少有一个产品具有有效价格和库存(这是相当多的逻辑).因此,如果您正在尝试对CUT进行单元测试,那么测试所有Brand.IsAvailable逻辑远远超出范围,因此模拟该方法是有意义的.

如果设置实体很容易,那么使用实体,例如,如果您有一个用户并且它有一个名为的属性active,您可以创建一个用户并在测试中将该属性设置为构建虚假用户和分配的成本该属性可能与模拟方法调用相同,并且(在我看来)更清晰.

我不是ac#expert,但我读过Isolator是.net的最佳框架之一,所以我会做你在1上提到的.