【问题标题】:Unit testing parameters sent into WCF service发送到 WCF 服务的单元测试参数
【发布时间】:2011-11-03 14:37:17
【问题描述】:

创建单元测试以测试我发送到 WCF 服务的参数的最佳方法是什么?

我有一个项目,其中有一个与我的 WCF 服务对话的存储库类。它看起来像这样:

public class MyRepository : IMyRepository
{
    public Customer GetCustomer(int customerId)
    {
        var client = new MyWCFServiceClient();
        MyWCFServiceCustomer customerWCF = client.GetCustomer(customerId);
        Customer customer = ConvertCustomer(customerWCF);
        return customer;
    }

    //Convert a customer object recieved from the WCF service to a customer of
    //the type used in this project.
    private Customer ConvertCustomer(MyWCFServiceCustomer customerWCF)
    {
        Customer customer = new Customer();
        customer.Id = customerWCF.Id;
        customer.Name = customerWCF.Name;
        return customer;
    }
}

(这显然是简化的)

现在我想编写单元测试来检查我从存储库发送到我的服务的参数是否正确。在上面的示例中,这有点毫无意义,因为我只在传入时发送 customerId,但在我的真实代码中,存储库类中有更多参数和更多逻辑。

问题是生成的服务客户端类(MyWCFServiceClient)没有接口,所以我不能在我的测试中模拟它(或者我错了吗?)。

编辑:我错了。有界面!请参阅下面的答案。

一种解决方案是拥有一个包装服务客户端的类,并且只重新发送参数并返回结果:

public class ClientProxy : IClientProxy
{
    public MyWCFServiceCustomer GetCustomer(int customerId)
    {
        var client = new MyWCFServiceClient();
        return client.GetCustomer(customerId);
    }
}
public interface IClientProxy
{
    MyWCFServiceCustomer GetCustomer(int customerId);
}

这样我可以给那个类一个接口,从而模拟它。但是编写那个“代理”类并保持更新似乎很乏味,所以我希望你有更好的解决方案! :)

【问题讨论】:

    标签: .net wcf unit-testing


    【解决方案1】:

    你应该看看这个帖子here

    您可以使用 ClientBase<IServiceContract> directly,而不是使用 ServiceReference 代理(buggy anyway - 处理客户端总是尝试关闭连接,即使它出现故障)。

    您可以使用由 ServiceReference 创建的代理服务合同接口,或者如果您可以控制链接的两端,那么您可以将 ServiceContract 接口构建到一个单独的程序集中并在客户端和服务器上共享它。

    【讨论】:

    • 这是我正在寻找的问题:当构造函数触发时,如何让 ClientBase 不构造 Channel?我已经将我的客户端拉入了一个抽象类,该类引入了 IService 和 ClientBase,然后我可以让控制器将其用作注入点。在执行单元测试时,在构造一个 mock/fake 时,ChannelFactory 仍然会寻找一个配置。嗯,也许我会尝试一下,然后空接它。
    【解决方案2】:

    我的错...实际上有一个生成的服务类的接口。多看的时候才发现。它只是没有我期望的名称(在我的示例中,如果客户端称为 MyWCFServiceClient,我希望接口称为 IMyWCFServiceClient,但它实际上称为 IMyWCFService)。

    所以我可以重写我的控制器来注入服务客户端,从而使其可模拟:

    public class MyRepository : IMyRepository
    {
        private readonly IMyWCFService _serviceClient;
    
        //Constructor
        public MyRepository(IMyWCFService serviceClient)
        {
            _serviceClient = serviceClient;
        }
    
        public Customer GetCustomer(int customerId)
        {
            MyWCFServiceCustomer customerWCF = _serviceClient.GetCustomer(customerId);
            Customer customer = ConvertCustomer(customerWCF);
            return customer;
        }
    
        //Convert a customer object recieved from the WCF service to a customer of
        //the type used in this project.
        private Customer ConvertCustomer(MyWCFServiceCustomer customerWCF)
        {
            Customer customer = new Customer();
            customer.Id = customerWCF.Id;
            customer.Name = customerWCF.Name;
            return customer;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多