在单元测试中托管WCF服务

时间:2012-07-19 16:51:12

标签: wcf unit-testing

我想要对我的自定义ServiceHostFactory进行单元测试。不幸的是,我在调用InvalidOperationException

时收到此CreateServiceHost
  

'ServiceHostFactory.CreateServiceHost'无法在当前托管环境中调用。此API要求将调用应用程序托管在IIS或WAS中。

我可以通过重构我的类来解决这个问题,它暴露了一个公共方法,它可以由单元测试直接调用,而不是使用它继承的公共接口;我不想仅仅为了单元测试而改变我的界面。我还看到另一个建议产生Cassini主机的SO答案,但我不想以这种方式使我的单元测试复杂化。

有没有办法解决这个ServiceHostFactory限制而不采取这些措施?

2 个答案:

答案 0 :(得分:5)

我想出了这个问题。在我的自定义ServiceHostFactory中,我只覆盖了受保护的方法CreateServiceHost(Type serviceType, Uri[] baseAddresses)。通过覆盖公共CreateServiceHost(string constructorString, Uri[] baseAddresses)方法,我能够构建服务主机工厂而没有任何问题。

在:

public class MyServiceHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        // ...
    }
}

后:

public class MyServiceHostFactory : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        return this.CreateServiceHost(typeof(MyService), baseAddresses);
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        // ...
    }
}

答案 1 :(得分:1)

这是我对这个问题的解决方案(我不是100%确定我们是否应该这样做。)

在单元测试夹具的设置中,设置托管环境(NUnit示例):

[TestFixtureSetUp]
public void TestFixtureSetup()
{
    if(!HostingEnvironment.IsHosted)
    {
        // The instance constructor hooks up the singleton hosting environment, ewww...
        new HostingEnvironment();

        // Check the hosting environment is fully initialized
        ServiceHostingEnvironment.EnsureInitialized();
    }
}

然后您可以在单元测试中自由使用自定义ServiceHostFactory

[Test]
public void ServiceHostIsCorrect()
{
    // Arrange
    var serviceType = typeof (string);
    var factory = new UnityServiceHostFactory();

    // Act
    var serviceHost = factory.CreateServiceHost(serviceType.AssemblyQualifiedName, new Uri[] {});

    // Assert
    Expect(serviceHost, Is.TypeOf<UnityServiceHost>());
    var unityServiceHost = (UnityServiceHost)serviceHost;
    Expect(unityServiceHost.Description.ServiceType, Is.EqualTo(serviceType));
}