单元测试Windows服务事件处理程序

时间:2015-02-27 18:22:06

标签: c# .net multithreading unit-testing tdd

我正在编写Windows服务,我想针对事件处理程序编写单元测试,以检查它们如何管理工作线程。我已经成功地管理了OnStart,OnStop和OnPause,但OnContinue让我有些焦虑。

Windows服务

Program.Main()

这不会产生任何异常 - 它只是将服务设置为运行。

MyService.cs 这有一个手动重置事件:

private static ManualResetEvent _resetEvent = new ManualResetEvent(false);

MyService.OnStart()

这将创建一个Worker线程,以便主线程可以继续侦听来自服务控制管理器的事件

MyService.OnStop()

检查Workerthread.IsAlive是否为true,如果是,则调用.Abort()就可以了。

MyService.OnPause()

检查Worker的ThreadState是否为Suspended | SuspendRequested,如果没有,则调用_resetEvent上的.Reset()。

注意:目前不确定这些是否是理想状态,或者我是否应该查看状态'WaitSleepJoin'。

MyService.OnContinue()

检查Worker的ThreadState是否为Suspended | SuspendRequested,如果是,则在_resetEvent上调用.Set()。

MyTests

OnStart()测试

这很简单,我只是调用Event Handler,它看到没有Worker线程,所以创建一个。

OnStop()测试

稍微复杂一些。在测试中,我创建了一个调用委托的线程,该委托将其发送到睡眠状态。然后我使用Reflection将其设置为Service中的Worker线程私有属性,然后调用OnStop()事件处理程序。这会找到正在休眠的已启动的工作线程,因此将其中止。

OnPause()测试

与OnStop()测试类似,但是我没有创建一个休眠线程,而是创建一个遍历一个小循环的循环(这个循环足够大,持续几秒钟)。当我调用OnPause()方法时,它找到正在工作的工作线程,并在_resetEvent上调用.Reset()。

OnContinue()测试

所以我的计划是模式化OnPause和OnStop测试,但这次创建一个当前暂停的工作线程。但是,在.NET 4.5中,Thread.Suspend()已过时。

因此我创建了一个本地ManualResetEvent [每单元测试一个;我有OnContinue()事件处理程序的多个单元测试],在我的委托方法中,工作线程正在运行,我将其设置为调用.WaitOne()。如果我运行一个测试,那么工作正常。但如果我将它们全部一起运行,那么每个测试的Unique ManualResetEvent似乎都会影响其他测试。

来自一个单元测试的示例代码,我创建了工作线程并将其注入到服务的私有线程方法中:

const BindingFlags InstanceFlags = 
    BindingFlags.Instance | BindingFlags.NonPublic;

PropertyInfo prop = t.GetProperty("MyWorkerThread", InstanceFlags);
EventWaitHandle wh2 = new ManualResetEvent(true);
var thread = new Thread(() =>
  {
    var sb = new Lazy<StringBuilder>();
    for (int i = 0; i < 10000000; i++)
    {
      wh2.WaitOne();
      sb.Value.Append(i.ToString());
    }
  });

thread.Start();
prop.SetValue(service, thread, null);

所以当我在另一个测试中复制它,但是有“wh3”而不是“wh2”时,那么我的测试似乎都会绊倒自己。

工具 使用Visual Studio 2013和NUnit测试运行器。

如果有人能够指出我出错的地方,或者更好的是,请指出一个更好的方法来实现这一目标,我将不胜感激。

非常感谢

格里夫

0 个答案:

没有答案