C# 如何确认在单元测试中对我的ServiceHost调用了Open()
我有一个windows服务正在打开两个WCF服务。我想对OnStart()进行单元测试,并断言正在调用service1.Open()和service2.Open()。OnStart()如下所示:C# 如何确认在单元测试中对我的ServiceHost调用了Open(),c#,unit-testing,mocking,rhino-mocks,servicehost,C#,Unit Testing,Mocking,Rhino Mocks,Servicehost,我有一个windows服务正在打开两个WCF服务。我想对OnStart()进行单元测试,并断言正在调用service1.Open()和service2.Open()。OnStart()如下所示: protected override void OnStart(string[] args) { // host WCF services _service1.Open(); _service2.Open(); } [TestMet
protected override void OnStart(string[] args)
{
// host WCF services
_service1.Open();
_service2.Open();
}
[TestMethod()]
public void WinServiceOnStartCallsDependenciesAsExpected()
{
ServiceHostBase service1 = MockRepository.GenerateStub<ServiceHostBase>();
ServiceHostBase service2 = MockRepository.GenerateStub<ServiceHostBase>();
WinService target = new WinService(service1, service2);
WinService_Accessor privateTarget = new WinService_Accessor(new PrivateObject(target));
privateTarget.OnStart(null);
我将服务注入构造函数重载中,如下所示:
public WinService(ServiceHostBase service1,
ServiceHostBase service2)
{
_service1 = service1;
_service2 = service2;
InitializeComponent();
}
我使用Rhinomock生成ServiceHostBase的存根,如下所示:
protected override void OnStart(string[] args)
{
// host WCF services
_service1.Open();
_service2.Open();
}
[TestMethod()]
public void WinServiceOnStartCallsDependenciesAsExpected()
{
ServiceHostBase service1 = MockRepository.GenerateStub<ServiceHostBase>();
ServiceHostBase service2 = MockRepository.GenerateStub<ServiceHostBase>();
WinService target = new WinService(service1, service2);
WinService_Accessor privateTarget = new WinService_Accessor(new PrivateObject(target));
privateTarget.OnStart(null);
[TestMethod()]
public void WinServiceOnStartCallsDependenciesAsExpected()
{
ServiceHostBase service1=MockRepository.GenerateSub();
ServiceHostBase service2=MockRepository.GenerateSub();
WinService目标=新的WinService(服务1,服务2);
WinService_访问器privateTarget=新的WinService_访问器(新的PrivateObject(target));
privateTarget.OnStart(空);
当我的测试调用OnStart()时,当它调用service1.Open()时,我会得到一个null引用异常。我已经确认service1在那一点上是一个模拟对象,并且抛出null的是Open()。我知道Open()实际上是System.ServiceModel.Channels.CommunicationObject上的一个方法,我也尝试了Stub或mock,但仍然得到了object ref错误。它不是一个虚拟方法,所以我认为它只是没有被mock版本覆盖,而是当我尝试设置expectionreportservice.Stub(r=>r.Open())时
,我得到了一个关于没有默认超时的不同异常,好像它运行的是实际的CommunicationObject Open()方法,而不是RhinoMocky抛出null ref
所有这些都是为了说明,我只是在寻找如何确认Open()的帮助正在单元测试中对我的ServiceHost进行调用。=]
ServiceHostBase。在引擎盖下打开
调用。作为其实现的一部分,它会执行许多不同的操作,例如验证对象的状态、创建其他对象、调用方法、属性等。由于它不是虚拟的(您的假设是正确的),Rhino将调用基类实现
要使其正常工作,您可能必须模拟和存根大量的通信对象
依赖项,并且仍然无法确定您是否会成功(某些类型/方法可能只是Rhino无法修改,认为是静态的、密封的或其他非虚拟的)。这就是为什么您应该:
.Open
ServiceHostBase
,并通过接口将其作为依赖项传递;这需要额外的工作(新接口和简单的包装类),但允许您完全按照自己的意愿执行请记住,添加包装器只会将问题进一步委托给包装器类“
Open
方法,该方法本质上将调用ServiceHostBase.Open
——您是否也应该进行单元测试?)。另一方面,集成测试可能无法像单元测试那样快速捕获问题(假设您运行它们的频率较低)取决于你认为通信对象
依赖项,并且仍然无法确定您是否会成功(某些类型/方法可能只是Rhino无法修改,认为是静态的、密封的或其他非虚拟的)。这就是为什么您应该:
.Open
ServiceHostBase
,并通过接口将其作为依赖项传递;这需要额外的工作(新接口和简单的包装类),但允许您完全按照自己的意愿执行请记住,添加包装器只会将问题进一步委托给包装器类“
Open
方法,该方法本质上将调用ServiceHostBase.Open
——您是否也应该进行单元测试?)。另一方面,集成测试可能无法像单元测试那样快速捕获问题(假设您运行它们的频率较低)取决于你认为《代码>OnOpen/<代码>》的重要性,你选择哪种方式或多或少是一个判断调用。 Yea,我在讨论包装方法,但是我认为我们将不得不把它暴露出来。调用永远不会是有条件的,因此这种风险似乎不值得付出额外的复杂性。如果没有令人惊讶的事情发生,我会将此标记为答案。是的,我在讨论包装器方法,但我认为我们必须让它暴露出来。Open()呼叫永远不会是有条件的,因此,这种风险似乎不值得付出额外的复杂性。如果没有令人惊讶的事情发生,我会将此标记为答案。