4

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

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

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

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

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

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

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

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

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

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

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

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

4

2 回答 2

1

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

于 2009-12-11T04:28:00.237 回答
0

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

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

You have already taken a large dependence on spring.net and going that extra distance to inject your mocks and force tests to use them sounds reasonable to me. There must be a way of modifying your config temporarily to use a specific Mock. If not consider a simple factory to be used by your service to allow you to get your Mocks in place.

于 2009-12-24T08:15:30.410 回答