Testing a Windows Service

When you tire of the cycle of

  • changing code,
  • compiling,
  • running service setup,
  • start service,
  • check that the service does what it is surposed to by attaching to the process,
  • stop service,
  • uninstalling service and finally
  • removing any log that the service made

then you might be wondering if you can do this a smarter way….

There is …..

….by using #if/#endif blocks. This should make you worry as this has been used and misused in all programming languages that has this feature. This makes the code more unpredictable and thus more prone to errors due to testing and overview difficulty.

I have written a blog post that is about using conditional builds (You can read it here)

But in this case the #if/#endif construct makes sence to use partly as we will not overdo it and partly that we move something from an annoying way of testing to an easier way.

The steps to do this are quite simple:

  1. Create a Windows Service project
  2. Create a class “MainApplication” that run your primary code
  3. Add the function calls to the service
  4. Create a dummy service called “DummyService” with the functions that you use in the service
  5. Add function calls to the dummy service
  6. Change the function “Main” in the “Program” class

You will probably need to change the way you normally program services with several lines of code in the OnStart and OnStop functions of the service which is a somewhat bad practice anyway and move them to the “MainApplication” class where they should have been anyway.

In this case the application and thus the service only log at start and stop. Make sure that the dummy service runs in a loop to make it act like a service.

The “MainApplication” looks like this:

public class MainApplication
{
private ILog _log = null;

public MainApplication()
{
log4net.Config.BasicConfigurator.Configure(
new log4net.Appender.FileAppender(new log4net.Layout.PatternLayout("%d - %m%n"), "testfile.log"));

_log = LogManager.GetLogger("ROOT");
}

public void functionForOnStart(string[] args)
{
_log.Info("functionForOnStart");
}

public void functionForOnStop()
{
_log.Info("functionForOnStop");
}
}

The changed service looks like this:

public partial class TestableService : ServiceBase
{
private MainApplication _mainApplication;

public TestableService()
{
InitializeComponent();
_mainApplication = new MainApplication();
}

protected override void OnStart(string[] args)
{
_mainApplication.functionForOnStart(args);
}

protected override void OnStop()
{
_mainApplication.functionForOnStop();
}
}

The dummy service looks like this:

public class DummyService
{
private MainApplication _mainApplication;

public DummyService()
{
_mainApplication = new MainApplication();
}

public void Run()
{
OnStart(null);
bool exit = false;
while(!exit)
{
// Make waiting routine
Thread.Sleep(10000);

// Recheck if stop should be done
exit = true;
}
OnStop();
}

protected void OnStart(string[] args)
{
_mainApplication.functionForOnStart(args);
}

protected void OnStop()
{
_mainApplication.functionForOnStop();
}
}

The “Main” looks like this:

private static void Main()
{
#if DEBUG
DummyService dummyService = new DummyService();
dummyService.Run();
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new TestableService()
};
ServiceBase.Run(ServicesToRun);
#endif
}

With these minor changes a difficult to test windows service turns into a easily testable program running unit tests and using breakpoints.

Leave a Reply

Your email address will not be published. Required fields are marked *