为伪造的Web服务代理类设置虚假存储库是一个好主意吗?

时间:2013-03-28 15:24:45

标签: web-services unit-testing proxy repository

在设置网络服务时,我可以让它使用存储库类来获取要发送回客户端的数据。如果我需要对服务完成的逻辑进行单元测试,我可以在其中注入一个虚拟存储库的引用,该存储库返回一些硬编码数据对象以避免调用数据库。

客户端上,假设我有一个基于MVC的Web应用程序,它通过服务代理调用此Web服务。 如果我想对MVC应用程序中的逻辑进行单元测试并提供代表服务返回的数据,我该如何伪造代理参考?我的想法是,尽管我不知道我对此充满信心,并想知道我是否可能错过了一个更简单的解决方案:

我可以设置一个代理接口(我们称之为 IProxy ),然后设置它的两个具体实现(比方说,代理 FakeProxy < / strong>)并为正在执行的情况注入一个(运行单元测试时为FakeProxy,实际生产应用程序为Proxy)。为了在不进行实际服务调用的情况下为单元测试生成一些示例数据,是否应该在假代理中实现假存储库(可能与上面的服务器方案中使用的相同)?我不确定如何最好地设置假代理类来协助测试我的客户端代码。

更新

我同意到目前为止发布的答案,但我已经考虑了他们的观点,所以让我提供一些示例C#代码,说明我为什么这么说。如果我从我的代理设计中留下一个虚假的存储库,我的伪代理可能看起来像这个非常简单的人为例子:

public class FakeCustomerProxy : ICustomerProxy
{
    private List<Customer> Customers;

    public FakeProxy()
    {
        Customers = new List<Customer>();

        Customers.Add(new Customer { Id = 1, Name = "Smith, John" });
        Customers.Add(new Customer { Id = 2, Name = "Johnson, Al" });
        Customers.Add(new Customer { Id = 3, Name = "Thomas, William" });
    }

    public Customer GetById(int customerId)
    {
        return Customers.Where(c => c.Id == customerId).FirstOrDefault();
    }
}

GetById()方法,而不是调用Web服务来获取所需的客户信息,而只是从嵌入在此类中的硬编码客户列表中返回它。这真的开始类似于我为假存储库设置的内容(我甚至可能在服务器端设置非常相似的代码来协助测试服务逻辑),所以我很好奇我是否应该考虑放置这些硬编码的客户引用到多个地方使用的专用虚假存储库类。 我是否可能认为这个假代理的设计完全错误?

2 个答案:

答案 0 :(得分:2)

不,为假网络服务代理设置假存储库似乎不是单元测试的好主意。

实际上,一般只有一个假(代理或存储库)就足够了。

我建议您查看模拟框架(例如MoqRhino Mock)。
使用模拟,您甚至不需要FakeProxy实现。在每个测试中,您可以轻松设置IProxy的单独模拟实现,它将根据您的需要执行:返回预定义数据,引发异常,验证传递的参数等。

因此,您不需要实施1或2个假类进行测试。

<强>更新
所以,我在这里看到两个选项:

  1. 具有不可重复使用的简单测试数据,这些数据特定于每个特定测试。您可能需要为每个测试或一组测试设置类似迷你存储库(大约1-3个项目)的内容;

  2. 拥有足够大的可重用虚拟存储库,这对于服务器端和服务器端都很常见。客户端代码。最有可能的是,您需要支持一些额外的工具来在客户端测试和服务器端测试中使用这个虚拟存储库。例如。您还需要FakeProxy来测试客户端代码。

  3. 您应该考虑这些选项并选择更适合您的选项。

    在我看来,选项1适用于单元测试,但选项2可能对集成测试很有用。

答案 1 :(得分:0)

不,您不应该在测试中重复执行repository-proxy连接。在代理端口和存储库之间迟早会有一些业务逻辑,你必须在服务器端和客户端,在FakeProxy中实现两次。

因此,您的FakeProxy模拟实例应该只从调用中返回原始数据。

另一方面,您可以在客户端测试中导入真正的Proxy类,并模拟存储库以进行测试,但这将是集成测试,而不是单元测试,并且将涉及在客户端测试中使用服务器端代码,这并非总是可行。