单元测试WCF合同是否匹配sync/async?

Sco*_*ner 9 .net c# wcf unit-testing asynchronous

无论服务如何实现,WCF都可以轻松地同步或异步调用服务.为了适应客户端使用ChannelFactory,服务甚至可以定义单独的同步/异步合同接口.例如:

public interface IFooService
{
    int Bar();
}

[ServiceContract(Name = "IFooService")]
public interface IAsyncFooService
{
    Task<int> BarAsync();
}
Run Code Online (Sandbox Code Playgroud)

这允许客户端引用合同版本,并且WCF自动转换实际的API调用.

提供两个合同版本的一个缺点是它们必须保持同步.如果您忘记更新一个,客户端可能会在运行时收到合同不匹配异常.

是否有一种简单的方法来对接口进行单元测试,以确保它们与WCF元数据视角相匹配?

Sco*_*ner 8

您可以检索ContractDescription并使用它WsdlExporter来生成WSDL.输出MetadataSet是XML可序列化的,因此您可以比较每个合同版本的表示以确保它们匹配:

    [TestMethod]
    public void ContractsMatch()
    {
        // Arrange
        string expectedWsdl = this.GetContractString<IFooService>();

        // Act
        string actualWsdl = this.GetContractString<IAsyncFooService>();

        // Assert
        Assert.AreEqual(expectedWsdl, actualWsdl);
    }

    private string GetContractString<TContract>()
    {
        ContractDescription description = ContractDescription.GetContract(typeof(TContract));
        WsdlExporter wsdlExporter = new WsdlExporter();

        wsdlExporter.ExportContract(description);
        if (wsdlExporter.Errors.Any())
        {
            throw new InvalidOperationException(string.Format("Failed to export WSDL: {0}", string.Join(", ", wsdlExporter.Errors.Select(e => e.Message))));
        }

        MetadataSet wsdlMetadata = wsdlExporter.GetGeneratedMetadata();

        string contractStr;
        StringBuilder stringBuilder = new StringBuilder();
        using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder))
        {
            wsdlMetadata.WriteTo(xmlWriter);
            contractStr = stringBuilder.ToString();
        }

        return contractStr;
    }
Run Code Online (Sandbox Code Playgroud)