【问题标题】:Unit testing a WCF service with multiple dependencies对具有多个依赖项的 WCF 服务进行单元测试
【发布时间】:2010-12-25 10:22:07
【问题描述】:

我当然希望有人能帮助缓解我的挫败感。我正在尝试找到一种对我的 WCF 服务实现类进行单元测试的好方法,但我发现提供解决方案的每个资源都仅限于只有一个方法/操作的服务。

就我而言,我有一个包含多个服务方法/操作的服务类。服务类的目的是为在核心应用程序中实现的行为提供接口。因此,每个方法/操作负责:

  1. 接受来自 来电者
  2. 验证对象的属性
  3. 创建一个实例 适用的 Command 对象 执行操作
  4. 映射请求对象的 Command 对象的属性。
  5. 执行命令对象
  6. 将结果映射到响应 对象
  7. 将响应返回给调用者

此外,服务方法处理任何发生的异常并返回 WCF 故障。

我们将 Spring.NET 用于 IoC (DI) 和 AOP。服务类由 Spring 实例化,这允许我们使用 Spring 的 ParameterValidation 方面来执行步骤 2。默认情况下,我们也使用 Spring 来执行步骤 3。

在大多数情况下,所有这些都运行良好。但是,当需要编写单元测试来验证服务方法的行为时,我陷入了试图找出正确方法来处理服务对多个 Command 对象(每个方法一个)的依赖关系的过程中。

让我们明确一点,我在模拟 Command 对象时没有问题(我们使用 Moq,顺便说一句),我在进行黑盒测试时也没有问题。我正在尝试对内部逻辑进行白盒测试,例如验证步骤 4 是否正确执行,或者如果 Command 对象抛出异常,则服务会正确处理它。对于这些,我使用 Command 对象的模拟实例。

问题是在被测对象具有多个依赖项的情况下找到最佳实践 - 特别是当我对正在运行的测试只对其中一个感兴趣时。

构造函数的 DI 方法并不实用,因为我需要为构造函数提供尽可能多的参数,就像我在服务上使用方法一样(而且可能很多)。 Setter 注入让我很担心,因为 setter 仅用于测试目的 - 而且,在许多情况下,它们的数量会很大。

该服务旨在将第 4 步委托给一个虚拟方法,默认情况下,该方法使用 Spring 来实例化 Command 对象,但范被覆盖以使用继承和覆盖方法返回模拟。但事实证明,这也很笨拙。

因此,在网上大量阅读展示各种解决方案的文章之后,但正如我所说,只用一种方法/操作反映服务,我正在寻找一种易于实施、维护的方法的指导并在处理包含多个方法和多个依赖项的实际服务时进行扩展。

请记住,我不能使用 Spring 来注入模拟的 Command 对象,因为我需要对模拟的引用才能设置它们并验证方法的行为。 (更不用说我的测试也依赖于 Spring 的正常工作。)

【问题讨论】:

  • 在我的最后一次演出中,我们找到了一种将模拟注入自托管服务的方法。 “单元测试”(这个阶段更多的是验收测试)称为轻量级客户端,该客户端调用被测服务。如果这符合您的需求,我会看看我是否可以挖掘代码并发布。
  • 听起来更像是一个功能测试,而不是我们正在寻找的。实际上,我应该更清楚地指出,我正在尝试将服务类实现作为“单元”进行测试。在这一点上,我什至没有使用 WCF。

标签: .net wcf unit-testing dependency-injection spring.net


【解决方案1】:

我通常让我的服务类只是真正功能的薄外观。在这种情况下,您可能会考虑放弃测试服务本身,而是让它将所有调用委托给多个内部对象之一,因为它们更具体,所以单独测试更容易。

【讨论】:

  • 这基本上就是我们正在做的,但我仍然想测试委派是否正常工作。例如,如果我更改了我的内部对象(我委托给的对象)的属性,那么该对象可能仍然可以正常工作,但我将不再在我的服务方法中正确映射 Request 对象。
【解决方案2】:

听起来您已经完成了大部分艰苦的工作。

由于您已经在使用 DI 容器,也许您可​​以简单地创建和注入拦截步骤 3 的 Mocks。然后您可以通过 DI 容器接收到的内容以及验证的行为来测试前两个步骤,然后您就可以拥有模拟返回您想要测试剩余步骤的任何内容。

您已经对 spring.net 产生了很大的依赖,并且花费额外的距离来注入您的模拟和强制测试以使用它们对我来说听起来很合理。必须有一种方法可以临时修改您的配置以使用特定的 Mock。如果不考虑使用一个简单的工厂供您的服务使用,以使您的 Mocks 就位。

【讨论】:

  • 我意识到我刚刚重复了您的最后一段,但如果 spring.net 妨碍了测试,那么请解决它。
猜你喜欢
  • 2021-09-26
  • 2013-09-26
  • 1970-01-01
  • 2013-05-10
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 2019-04-12
相关资源
最近更新 更多