我想要对我的自定义ServiceHostFactory
进行单元测试。不幸的是,我在调用InvalidOperationException
:
CreateServiceHost
'ServiceHostFactory.CreateServiceHost'无法在当前托管环境中调用。此API要求将调用应用程序托管在IIS或WAS中。
我可以通过重构我的类来解决这个问题,它暴露了一个公共方法,它可以由单元测试直接调用,而不是使用它继承的公共接口;我不想仅仅为了单元测试而改变我的界面。我还看到另一个建议产生Cassini主机的SO答案,但我不想以这种方式使我的单元测试复杂化。
有没有办法解决这个ServiceHostFactory
限制而不采取这些措施?
答案 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));
}