我有像Miguel Castro建议的WCF服务结构 . 这意味着我已手动设置所有内容,并使用ServiceHost对象托管我的服务的控制台应用程序 .
我想保持我的服务类很薄,他们目前只是调用行为类 . 我现在的问题是单元测试服务类 . 我想向类中注入一些东西作为构造函数参数,这样我就可以模拟它并编写适当的隔离单元测试 . ServiceHost类似乎不接受参数,所以我的问题是如何将数据注入服务类 - 或者我不能?
我有像Miguel Castro建议的WCF服务结构 . 这意味着我已手动设置所有内容,并使用ServiceHost对象托管我的服务的控制台应用程序 .
我想保持我的服务类很薄,他们目前只是调用行为类 . 我现在的问题是单元测试服务类 . 我想向类中注入一些东西作为构造函数参数,这样我就可以模拟它并编写适当的隔离单元测试 . ServiceHost类似乎不接受参数,所以我的问题是如何将数据注入服务类 - 或者我不能?
4 回答
WCF支持 Constructor Injection ,但你必须通过一些箍来实现目标 . 关键在于编写自定义ServiceHostFactory . 虽然这也必须有默认构造函数,但您可以使用它来连接所有正确的行为 .
作为一个例子,我最近写了一个使用Castle Windsor来连接服务实现的依赖关系 . CreateServiceHost的实现只是这样做:
其中
this.container
是已配置的IWindsorContainer .WindsorServiceHost看起来像这样:
和WindsorInstanceProvider看起来像这样:
这可能看起来很多,但请注意它是可重复使用的通用代码,具有相当低的圈复杂度 .
您可以遵循相同的编码习惯用另一个DI容器或使用穷人的DI实现依赖注入 .
这是使用穷人的DI的这个成语的older writeup .
如果你使用Castle Windsor,它有一个很棒的WCF集成工具,可以让你做到这一点,而且非常容易 .
你是否将服务配置为Singleton?我发现使用DI容器创建服务实例时,IInstanceProvider实现可能会有问题 .
文章Hosting a Mock as a WCF service包含一个静态方法,该方法将根据使用单个 endpoints 传递给方法的对象生成WCF服务主机 .
该方法也发布在answer中Recommended patterns for unit testing web services .
使用示例调用NSubstitute,但可以使用其他模拟freameworks .