单元测试 - 如何使用MOQ MOQ WCF客户端

时间:2016-10-18 14:49:50

标签: c# wcf unit-testing moq

我一直在看many other questions on SO,许多相似,但似乎没有一个符合服务参考的风格,因此我问。他们中的大多数人都在谈论使用ChannelFactory,但这个使用ClientBase。我正在了解有关单元测试的更多信息。起订量。我想测试我们的存储库类,它调用WCF服务。

我尝试过这么多方法,包括在repo上创建构造函数,使用FISP接口。

如何使用它在repo中使用并且还可以单元测试,使用moq模拟WCF操作?

存储库尚未在界面中传递(如下)。它使用代理客户端类。

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.aUrl.com/fwi", ConfigurationName="FISP.FISP")]
public interface FISP {
    [System.ServiceModel.OperationContractAttribute(Action="http://www.aUrl.com/fwi/FISP/getPersonRequest", ReplyAction="http://www.aUrl.com/fwi/FISP/getPersonResponse")]
    [System.ServiceModel.FaultContractAttribute(typeof(FhSoap.FISP.FWiException), Action="http://www.aUrl.com/fwi/FISP/getPerson/Fault/FWiException", Name="FWiException")]
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(episodeTask))]
    [return: System.ServiceModel.MessageParameterAttribute(Name="person")]
    FhSoap.FISP.getPersonResponse getPerson(FhSoap.FISP.getPersonRequest request);  
}

生成的参考

这是生成的参考代码 -

接口

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface FISPChannel : FhSoap.FISP.FISP, System.ServiceModel.IClientChannel {
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class FISPClient : System.ServiceModel.ClientBase<FhSoap.FISP.FISP>, FhSoap.FISP.FISP {
    public FISPClient() {
    }

    public FISPClient(string endpointConfigurationName) : 
            base(endpointConfigurationName) {
    }

    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    FhSoap.FISP.getPersonResponse FhSoap.FISP.FISP.getPerson(FhSoap.FISP.getPersonRequest request) {
        return base.Channel.getPerson(request);
    }

    public FhSoap.FISP.person getPerson(FhSoap.FISP.personRequest request) {
        FhSoap.FISP.getPersonRequest inValue = new FhSoap.FISP.getPersonRequest();
        inValue.request = request;
        FhSoap.FISP.getPersonResponse retVal = ((FhSoap.FISP.FISP)(this)).getPerson(inValue);
        return retVal.person;
    }
}

客户端:

    public FisPRepository()
    {
        var factory = new ChannelFactory<FISPChannel>("BasicHttpBinding_SomthingService");

        var credentialBehaviour = factory.Endpoint.Behaviors.Find<ClientCredentials>();
        credentialBehaviour.UserName.UserName = "xyz";
        credentialBehaviour.UserName.Password = "cba";

        _fisPClient = factory.CreateChannel();
    }

更新

根据以下评论中的建议,我尝试使用界面构建客户端,这是什么意思?由于没有创建客户端,它会创建一个频道。

src

_fisPClient = factory.CreateChannel(); 无效,因为它会创建一个FISPChannel,而不是客户端。我错过了什么?

1 个答案:

答案 0 :(得分:0)

  

您的存储库正在与您的具体客户端一起工作,您需要将客户端注入到接口

的类中

响应:

  

@ Kritner,FISPChannel?与FISP接口相反?

嗯,通常的约定是接口是&#34;我&#34;类似IFISP之类的内容,无论哪种方式,IFISP界面都是我过去使用的界面(而不是IFISPChannel。但是目前,如果您尝试使用FISP },在新建客户端时,该界面无法访问您当前在班级中设置的ClientCredentials

理想情况下,您不会在每个存储库上设置凭据,而是在某种配置中。一旦你完成了这个,你就可以重构这样的事情:

public class FisPRepository : IFisPRepository
{
    private readonly FISP _fisp;

    public FisPRepository(FISP fisp)
    {
        _fisp = fisp;
    }

    public person GetPersonFromId(string id)
    {
        return _fisP.getPerson(new personRequest()
        {
            reference = new referenceFilter { type = "FWI", value = id },
        });
    }
}

当然,在构建存储库时,您需要传递客户端的具体内容 - 但是对于单元测试,您将能够模拟FISP

您可以通过多种方式获得客户的具体结果。

  • 使用NOC,Unity,AutoFac等IOC容器
  • 直接新建这个凝固物
  • 使用服务地点

由于语法因您的IOC或服务地点而异,所以现在您可以直接获取存储库:

FisPRepository myRepo = new FisPRepository(new FISPClient());

将您的具体化和编码注入抽象是design pattern称为依赖注入。