如何模拟由 Visual Studio 自动生成的 SOAP 客户端?

我有一个自动生成的 SOAP 客户端。它是由 Visual Studio 向导生成的(添加连接的服务 -> Microsoft WCF Web 服务参考提供程序)。我想模拟该客户端,因此当调用方法时,将以 SOAP 响应的格式返回预定义的结果。不幸的是,我无法让它工作 - 我的结果要么为空(而不是在 .Returns 中定义),要么得到异常。


我正在尝试在我的设计中应用干净的架构。因此,这个 SOAP 客户端进入了我的基础设施层,我在其中为其创建了一个存储库。该存储库创建 DTO,因此可以将它们分派到我的持久性中。存储库通过依赖项注入接收 SOAP 客户端。我还想对存储库进行测试,只是为了验证 DTO 生成是否正确。因此,我想模拟这个 SOAP 服务,这样我就可以将其提供给存储库并测试返回的 DTO。


自动生成的界面:


    public interface ApplicationSoap

    {

        [System.ServiceModel.OperationContractAttribute(Action = "http://Application/GetAppVersion", ReplyAction = "*")]

        Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(ExtApp.GetAppVersionRequest request);

    }


和自动生成的客户端类:


    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1-preview-30514-0828")]

    public partial class ApplicationSoapClient : System.ServiceModel.ClientBase<ExtApp.ApplicationSoap>, ExtApp.ApplicationSoap

    {


        static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);


        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]

        System.Threading.Tasks.Task<ExtApp.GetAppVersionResponse> ExtApp.ApplicationSoap.GetAppVersionAsync(ExtApp.GetAppVersionRequest request)

        {

            return base.Channel.GetAppVersionAsync(request);

        }


        public System.Threading.Tasks.Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(int appVer)

        {

            ExtApp.GetAppVersionRequest inValue = new ExtApp.GetAppVersionRequest();

            inValue.Body = new ExtApp.GetAppVersionRequestBody();

            inValue.Body.appVer = appVer;

            return ((ExtApp.ApplicationSoap)(this)).GetAppVersionAsync(inValue);

        }

    }


它运行,但调用的结果是null。我期望返回一个具有非空Body属性且内部有数组的对象。我正在寻求如何使这件事发挥作用的建议。


繁星点点滴滴
浏览 121回答 1
1回答

哔哔one

您的 SOAP 客户端合同是:public interface ApplicationSoap{&nbsp; &nbsp; [System.ServiceModel.OperationContractAttribute(Action = "http://Application/GetAppVersion", ReplyAction = "*")]&nbsp; &nbsp; Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(ExtApp.GetAppVersionRequest request);}您可以将其用作存储库中的依赖项,如下所示:public class Repository{&nbsp; &nbsp; private readonly IApplicationSoap _client;&nbsp; &nbsp; public Repository(IApplicationSoap client) { _client = client; }&nbsp; &nbsp; public async Task<AppVersion> GetAppVersionAsync(int version)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var request = new GetAppVersionRequest(new GetAppVersionRequestBody(version));&nbsp; &nbsp; &nbsp; &nbsp; var response = await _client.GetAppVersionAsync(request);&nbsp; &nbsp; &nbsp; &nbsp; return new AppVersion&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Version = response.Body.Version,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StartDate = response.Body.StartDate,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EndDate = response.Body.EndDate&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }}在这种情况下,您可能需要测试将输入转换为请求的代码以及将响应转换为 DTO 的代码。这是您唯一的代码(而不是由工具生成)。为此,您需要在存储库测试中模拟(实际上是存根)SOAP 客户端合约,并让它返回您想要的响应:[Fact]public async Task GetAppVersionAsync(){&nbsp; &nbsp; // arrange&nbsp; &nbsp; var client = new Mock<IApplicationSoap>(); // mock the interface, not the class!&nbsp; &nbsp; var result = new AppVersion&nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Version = 1,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; StartDate = DateTime.Parse("2010-01-01"),&nbsp; &nbsp; &nbsp; &nbsp; EndDate = DateTime.Parse("2015-12-31")&nbsp; &nbsp; };&nbsp; &nbsp; client.Setup(x => x.GetAppVersionAsync(It.IsAny<GetAppVersionRequest>))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Returns(Task.FromResult(new GetAppVersionResponse(new GetAppVersionResponseBody(result))));&nbsp; &nbsp; var repository = new Repository(soapApp);&nbsp; &nbsp; // act&nbsp; &nbsp; var dto = await repository.GetAppVersionAsync(1);&nbsp; &nbsp; // assert (verify the DTO state)&nbsp; &nbsp; Assert.Equal(1, dto.VersionNumber);&nbsp; &nbsp; Assert.Equal(new DateTime(2010, 1, 1), dto.StartDate);&nbsp; &nbsp; Assert.Equal(new DateTime(2015, 12, 31), dto.EndDate);}然而......仅仅因为您可以这样做并不意味着您应该这样做。
打开App,查看更多内容
随时随地看视频慕课网APP