Wanting a simple example of how to spin up and host a WCF endpoint and proxy for integration testing, I came up with the following simple example.

IFooService.cs


using System.ServiceModel;
using System.ServiceModel.Web;

namespace Test.SomeDir
{
    [ServiceContract]
    public interface IFooService
    {
        [WebGet(UriTemplate = "/ping")]
        [OperationContract]
        string Ping();
    }
}

FooService.cs


namespace Test.SomeDir
{
    public class FooService : IFooService
    {
        public string Ping()
        {
            return "Ping";
        }
    }
}

FooServiceTest.cs


using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
using NUnit.Framework;
using Test.SomeDir;

namespace Test
{
    public class FooServiceTest
    {
        [TestFixture]
        public class When_spec
        {
            private ServiceHost host;
            private IFooService proxy;

            [SetUp]
            public void SetUp()
            {
                host = new WebServiceHost(typeof(FooService));
                host.Open();
                proxy = CreateProxy();
            }

            [TearDown]
            public void TearDown()
            {
                host.Close();
            }

            [Test]
            public void Should_observation()
            {
                proxy.Ping();
            }

            private IFooService CreateProxy()
            {
                EndpointAddress ep = new EndpointAddress("http://localhost:1980/abc");

                var binding = new CustomBinding(
                    new TextMessageEncodingBindingElement(MessageVersion.None, Encoding.UTF8),
                    new HttpTransportBindingElement { ManualAddressing = true });

                var factory = new ChannelFactory<IFooService>(binding, ep);
                factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

                return factory.CreateChannel();
            }
        }
    }
}

The unit test above dynamically spins up a WCF WebServiceHost service which automatically sets some http bindings and behaviour configuration for us.

All we need to do now is add some information to our App.config file like this.

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    <services>
      <service name="Test.SomeDir.FooService"> <!-- this needs to be the fully qualified name of the service from your test -->
        <endpoint address="abc" binding="webHttpBinding" contract="Test.SomeDir.IFooService" /> <!-- address can be anything -->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1980" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  
</configuration>

And voila! You are done.

Couple things to be aware of.

1. The name in the configuration has to exactly match fully qualified name used to spin up our host.

            [SetUp]
            public void SetUp()
            {
                host = new WebServiceHost(typeof(FooService));
                host.Open();
                proxy = CreateProxy();
            }

Needs to be expanded to the following in your config.

<service name="Test.SomeDir.FooService">

Get this wrong and you will get the following error:

System.InvalidOperationException : Service ‘Test.SomeDir.FooService’ has zero application (non-infrastructure) endpoints.

2. Note the end point address ‘abc’.

<endpoint address="abc"

This need to map to the path the immediately follows the base host address in your URL;

http://localhost:1980/abc

Hope this helps. I find writing a test like this useful for testing my end points and making sure I’ve got everything setup.

A good book for learning more WCF is Learning WCF: A Hands-on Guide

Advertisement