简体   繁体   中英

How to programmatically generate WSDL from WCF service (Integration Testing)

I am looking to write some integration tests to compare the WSDL generated by WCF services against previous (and published) versions. This is to ensure the service contracts don't differ from time of release.

I would like my tests to be self contained and not rely on any external resources such as hosting on IIS.

I am thinking that I could recreate my IIS hosting environment within the test with something like...

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();
}

Does anyone else have any better ideas?

EDIT: Obviously this code is simply creating a host for the service, I am still missing the client code to obtain the WSDL definition.

Just use WebClient and ?wsdl sufix in URL

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);
}

Check out the WsdlExporter on MSDN. Its used to generate wsdl in WCF. You could also have a look in svcutil with reflector to see how its generating the wsdl information, since the tool can generate wsdl from a dll-file.

Another way to do your comparison would be to use the svcutil tool to generate the wsdl and compare it to a saved/baselined version of the service. Run the svcutil in your test and verify the output against the old files. Not really self-contained test since you'll need the svcutil...

How about something like this? Creating a WSDL using C#

Same answer translated to 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

One thing you need to be careful of is to compare the entire WSDL. WCF breaks up WSDLs, unlike classic web services (asmx) WSDLs. This means that the core of the info is on the ?WSDL page, however, there will also be multiple XSDs (.svc?XSD=XSD0, 1, 2 ...) and possibly multiple WSDL pages (?WSDL and ?WSDL=WSDL0 for example).

One way to accomplish this would be to generate a webrequest to get the data from the root wsdl. Then you can search the WSDL for anything like (yourServicename).svc?WSDL=WSLD0 and (yourServicename)?XSD=XSD0 and so on, spawning additional webrequests for each WSDL and XSD.

You might be better off using SoapUI to test the WSDL rather than relying on NUnit directly.

If you want to call SoapUI from NUnit, it's possible, but a little clunky. See http://enthusiasm.soapui.org/forum/viewtopic.php?f=2&t=15 for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM