.NET 框架:2.0 首选语言:C#
我是 TDD(测试驱动开发)的新手。
首先,是否可以对 Windows 服务进行单元测试?
Windows 服务类派生自 ServiceBase,它具有可覆盖的方法,
- 启动
- 停车
我怎样才能触发这些方法被调用,就好像单元测试是一个以正确顺序调用这些方法的实际服务一样?
在这一点上,我什至在做单元测试吗?还是集成测试?
我看过 WCF 服务问题,但这对我来说没有任何意义,因为我从未处理过 WCF 服务。
.NET 框架:2.0 首选语言:C#
我是 TDD(测试驱动开发)的新手。
首先,是否可以对 Windows 服务进行单元测试?
Windows 服务类派生自 ServiceBase,它具有可覆盖的方法,
我怎样才能触发这些方法被调用,就好像单元测试是一个以正确顺序调用这些方法的实际服务一样?
在这一点上,我什至在做单元测试吗?还是集成测试?
我看过 WCF 服务问题,但这对我来说没有任何意义,因为我从未处理过 WCF 服务。
我可能会建议设计您的应用程序,以便 Windows 服务中的“OnStart”和“OnStop”覆盖仅调用类库程序集上的方法。这样,您可以针对类库方法自动执行单元测试,并且该设计还将您的业务逻辑从 Windows 服务的实现中抽象出来。
在这种情况下,在 Windows 服务上下文中测试“OnStart”和“OnStop”方法本身将是一个集成测试,而不是您需要自动化的东西。
我通过不直接测试服务,而是测试服务的功能,对 Windows 服务进行了单元测试。
通常,我为服务创建一个程序集,为服务的功能创建另一个程序集。然后我针对第二个程序集编写单元测试。
这种方法的好处是您的服务非常薄。基本上它所做的只是调用方法在正确的时间做正确的工作。您的另一个程序集包含您的服务打算做的所有工作。这使得测试变得非常容易,并且可以根据需要轻松重用或修改。
我会从这里开始。它展示了如何在 C# 中启动和停止服务
一个开始的样本是
public static void StartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch
{
// ...
}
}
我还主要通过控制台应用程序测试服务,模拟服务会做什么。这样我的单元测试就完全自动化了。
我会使用windows服务类(你在启动/停止服务时运行的那个)有点像你真实系统的代理。我看不出您的服务背后的代码应该与任何其他编程有何不同。onStart 和 onStop 方法只是被触发的事件,例如按下 GUI 上的按钮。
所以你的windows服务类是一个很薄的类,堪比windows窗体。它调用您的业务逻辑/域逻辑,然后执行它应该做的事情。您所要做的就是确保您在 onStart 和 onStop 中调用的方法正常工作。至少那是我会做的;-)
为测试而设计是一个很好的策略,正如许多答案所指出的那样,建议您通过委派给域对象来保持OnStart
和方法保持非常精简。OnStop
但是,如果您的测试出于某种原因确实需要执行服务方法,您可以使用这样的代码从测试方法中调用它们(OnStart
在此示例中调用):
serviceInstance.GetType().InvokeMember("OnStart", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, serviceInstance, new object[] {new string[] {}});
自动关机、关机条件下的测试窗口服务 网络断开、连接时的测试窗口服务 测试窗口服务选项自动启动、手动等
盖伊可能是最好的答案。
无论如何,如果你真的想要,你可以在单元测试中调用这两种方法,如MSDN 文档所述,但是,由于它们受到保护,你需要使用反射。