如何从WCF服务以编程方式生成WSDL(集成测试)

如何从WCF服务以编程方式生成WSDL(集成测试),wcf,nunit,wsdl,integration-testing,Wcf,Nunit,Wsdl,Integration Testing,我希望编写一些集成测试,将WCF服务生成的WSDL与以前(和发布的)版本进行比较。这是为了确保服务合同与发布时间不存在差异 我希望我的测试是自包含的,不依赖任何外部资源,例如在IIS上托管 我在想,我可以在测试中重新创建我的IIS托管环境,比如 using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), new Uri("http://localhost:8000/Omega"))) { host.AddServic

我希望编写一些集成测试,将WCF服务生成的WSDL与以前(和发布的)版本进行比较。这是为了确保服务合同与发布时间不存在差异

我希望我的测试是自包含的,不依赖任何外部资源,例如在IIS上托管

我在想,我可以在测试中重新创建我的IIS托管环境,比如

using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), new Uri("http://localhost:8000/Omega")))
{
    host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary");
    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
    behavior.HttpGetEnabled = true;
    host.Description.Behaviors.Add(behavior);
    host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
    host.Open();
}
还有谁有更好的主意吗

编辑:
显然,这段代码只是为服务创建了一个主机,我仍然缺少获取WSDL定义的客户机代码。

您需要注意的一件事是比较整个WSDL。与经典web服务(asmx)WSDL不同,WCF分解了WSDL。这意味着信息的核心在?WSDL页面上,但是,也会有多个XSD(.svc?XSD=XSD0,1,2…)和可能的多个WSDL页面(例如WSDL和?WSDL=WSDL0)


实现这一点的一种方法是生成webrequest以从根wsdl获取数据。然后,您可以在WSDL中搜索(yourServicename).svc?WSDL=WSLD0和(yourServicename)?XSD=XSD0等内容,从而为每个WSDL和XSD生成额外的webrequests

您最好使用测试WSDL,而不是直接依赖NUnit

如果您想从NUnit调用SoapUI,这是可能的,但有点笨重。有关更多信息,请参阅。

查看MSDN上的。它用于在WCF中生成wsdl。 您还可以查看svcutil with reflector,了解它是如何生成wsdl信息的,因为该工具可以从dll文件生成wsdl


进行比较的另一种方法是使用svcutil工具生成wsdl,并将其与服务的已保存/基线化版本进行比较。在测试中运行svcutil,并根据旧文件验证输出。不是真正的自包含测试,因为您需要svcutil…

像这样的东西怎么样?

只需在URL中使用WebClient和?wsdl sufix即可

using (ServiceHost host = new ServiceHost(typeof(NSTest.HelloNS), new Uri("http://localhost:8000/Omega"))) { host.AddServiceEndpoint(typeof(NSTest.IMy_NS), new BasicHttpBinding(), "Primary"); ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; host.Description.Behaviors.Add(behavior); host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); host.Open(); string wsdl = null; using (WebClient wc = new WebClient()) { using (var stream = wc.OpenRead("localhost:8000/Omega?wsdl")) { using (var sr = new StreamReader(stream)) { wsdl = sr.ReadToEnd(); } } } Console.Write(wsdl); } 使用(ServiceHost host=新ServiceHost(typeof(NSTest.HelloNS)), 新Uri(“http://localhost:8000/Omega"))) { AddServiceEndpoint(typeof(NSTest.IMy_NS),新的BasicHttpBinding(),“Primary”); ServiceMetadataBehavior行为=新ServiceMetadataBehavior(); behavior.HttpGetEnabled=true; host.Description.Behaviors.Add(行为); AddServiceEndpoint(typeof(imeAdataExchange),MetadataExchangeBindings.CreateMexHttpBinding(),“mex”); host.Open(); 字符串wsdl=null; 使用(WebClient wc=new WebClient()) { 使用(var stream=wc.OpenRead(“localhost:8000/Omega?wsdl”)) { 使用(var sr=新的StreamReader(stream)) { wsdl=sr.ReadToEnd(); } } } 编写(wsdl); }
同样的答案翻译成VB

    Using host = New ServiceHost(GetType(MyHelloWorldWcfLib.HelloWorldServer), New Uri("http://localhost:8000/Omega"))

        host.AddServiceEndpoint(GetType(MyHelloWorldWcfLib.IHelloWorld), New BasicHttpBinding(), "Primary")
        Dim behavior = New ServiceMetadataBehavior()
        behavior.HttpGetEnabled = True
        host.Description.Behaviors.Add(behavior)
        host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex")
        host.Open()

        Dim wsdl As String = Nothing
        Using wc = New System.Net.WebClient()
            Using stream = wc.OpenRead("http://localhost:8000/Omega?wsdl")
                Using sr = New IO.StreamReader(stream)
                    wsdl = sr.ReadToEnd()
                End Using
            End Using
        End Using
        Console.Write(wsdl)
    End Using

比较文件是错误的。文件可以在语义不变的情况下更改。