9

我通过方法链创建了一些小的流畅接口。他们通常调用一些从 web 服务/数据库中获取数据的存储库。

我应该如何进行使用流畅接口的单元测试方法?

Public IEnumberable<Computer> FindComputers(string serialNumber)
{
      return Computers.FindBySerialNumber("YBCX00900")
         .AttachConfiguration()
         .EnsureAllComputersHaveConfiguration();
}

我可以对 fluent interface 的各个组件进行单元测试,但是如果我想对上面的 FindComputers 方法进行单元测试,我应该怎么做?

  1. 使用fluent接口的具体实现,在Repository类上写期望
  2. 模拟流畅的界面本身并对其设定期望
  3. 仅测试 fluent 接口本身,而不是 FindComputers() 方法

我想找到一种易于维护的方法。

4

3 回答 3

3

我认为 FI 做的比它需要的要多。我假设您使用计算机作为数据映射器,并且还使用它来构建查询。根据您所显示的查询是由此建立的:

rule 1: find configured computer with serial number = "whatever" and has-config = true.
rule 2: find not-config computer with serial number = "whatever and has-config = true.
rule 3: find configured computer with serial number = "whatever" and has-config = false.
rule 4: find not-config computer with serial number = "whatever" and has-config = false.
rule 5: find all computer with serial number = "whatever" and has-config = true.
rule 6: find all computer with serial number = "whatever" and has-config = false.

等等...

现在,其中一些可以实施的规则似乎是不正确的。规则 2 和规则 3 似乎有交叉的目的。规则 5 和规则 6 做什么?这是对的吗?

因为您已经实现了一个破坏 SRP 的对象。第一步是将查询构建器从数据映射器中分离出来。构建您的 FI 查询对象,然后将其传递给映射器。

现在您可以测试FindComputers以确保将 FI 查询对象发送到数据映射器。因为您现在可以构建一个 FI 查询对象,所以您可以对其进行测试。您可以测试数据映射器是否使用查询对象。

如果将来您想按位置查找计算机怎么办。如果您保留与您编写的代码相同的代码,则必须添加一个方法FindByLocation并且在您知道它之前,您已经拥有了一个上帝对象。臭!

于 2009-08-18T16:02:46.500 回答
1

你可以模拟你的存储库吗?虽然有些人会提倡一种更纯粹的方法,您必须隔离一个类的一个方法,但这将是测试 FindComputers 和 fluent 接口如何协同工作的好方法。而且它可能更简单,这取决于存储库访问层的样子。

于 2009-08-17T22:50:22.363 回答
0

我会做2+3。假设流利的接口是真正的接口,它们应该相对容易模拟。只要意识到调用链中的每一步都应该返回一个新的模拟对象,这反过来又期待链中的下一个调用。

不过,您仍然应该直接测试 fluent 接口,模拟它们下面的存储库层。

于 2009-08-17T22:26:56.233 回答