【问题标题】:Unit testing a object that has dependency on wcf service对依赖于 wcf 服务的对象进行单元测试
【发布时间】:2013-09-26 13:12:10
【问题描述】:

我正在尝试编写一个依赖于 WCF 服务的类,并且我希望我的类可以进行单元测试。我想出了下面的代码,但遇到了一些棘手的情况

public class BenefitReason
{
    private IWCFServiceClient _client;

    public  BenefitReason(IWCFServiceClient client)
    {
       _client = client;
    }

    public CanIssueEmercengyBenefit(string benefitReasonCode)
    {
         client.GetEmergencyBenefits().contains(benefitReasonCode);
    }
    //Rest of implementation for Benefit Reason
}

这是可单元测试的,因为我可以模拟 IWCFServiceClient,但是我失去了对客户端的控制。如果客户端通道在创建BenefitReason 对象和调用CanIssueEmercengyBenefit 之间关闭,则会发生异常。

请就如何克服编写可进行单元测试的代码与失去对 wcf 客户端实例化的控制的棘手情况提出建议。

【问题讨论】:

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


    【解决方案1】:

    一种选择是在接口实现的每个方法调用中实例化和处置 WCF 服务客户端。

    请参阅What is the best workaround for the WCF client `using` block issue? 以正确处理处置。

    【讨论】:

      【解决方案2】:

      除了 TrueWill 的答案,您可以为此构建一个代理:

      public WCFServiceClientProxy : IWCFServiceClient
      {
          public Benefit[] GetEmergencyBenefits()
          {
              using (var client = new WCFServiceClient())
              {
                  return client.GetEmergencyBenefits();
              }
          }
      }
      

      通过在每次调用中注入WCFServiceClientProxy,您可以防止任何失败并让客户端不知道 WCF 服务。

      当您使用它时,请避免调用该接口 IWCFServiceClient,因为它不应该关心客户端是调用 WCF 服务还是数据库。

      【讨论】:

      • +1 有两个建议:(1)以不同的方式处理 WCF 客户端(请参阅我的答案中的链接)和(2)从代理返回数组以外的东西(数组是实现细节)。
      • @TrueWill:关于第 (1) 点。感谢您的参考。我对此一无所知。不过我不同意你的第二点。 List 是一个实现细节,一个数组只是一个原始结构,这表明该类不会保留该集合(与返回 Collection<T> 相比,这意味着保留一个引用)。此外,这只是一个例子:-)。
      • 谢谢 - 我想更多的是IEnumerable<Benefit>。这样,如果 OP 稍后将实现更改为数据库或其他任何内容,则不必将结果转换为数组。至于using 的问题,很少有人知道这一点。这是微软无视自己标准的一个令人震惊的案例。
      • @TrueWill 我会惊恐地阅读 MSDN 文章。 WCF 团队未能遵循框架设计指南,这种行为非常糟糕。他们搞砸了。
      猜你喜欢
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2010-10-03
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多