Używam usługi Topshelf do obsługi usługi systemu Windows napisanej w języku C#, a teraz chcę napisać kilka testów integracji. Mój kod inicjalizacji odbywa się w klasie wyrzutni jak następuje:Testy integracyjne na górnej półce, aby uruchomić usługę Windows # C#
public class Launcher
{
private Host host;
/// <summary>
/// Configure and launch the windows service
/// </summary>
public void Launch()
{
//Setup log4net from config file
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(DEFAULT_CONFIG));
//Setup Ninject dependency injection
IKernel kernel = new StandardKernel(new MyModule());
this.host = HostFactory.New(x =>
{
x.SetServiceName("MyService");
x.SetDisplayName("MyService");
x.SetDescription("MyService");
x.RunAsLocalSystem();
x.StartAutomatically();
x.Service<MyWinService>(s =>
{
s.ConstructUsing(() => kernel.Get<MyWinService>());
s.WhenStarted(w => w.Start());
s.WhenStopped(w => w.Stop());
});
});
this.host.Run(); //code blocks here
}
/// <summary>
/// Dispose the service host
/// </summary>
public void Dispose()
{
if (this.host != null && this.host is IDisposable)
{
(this.host as IDisposable).Dispose();
this.host = null;
}
}
}
chcę napisać kilka testów integracyjnych, aby upewnić się, że log4net i Ninject się prawidłowo skonfigurowany i Topshelf uruchamia moją usługę. Problem polega na tym, że po wywołaniu Run()
na hoście Topshelf, kod blokuje się, więc mój kod testowy nigdy nie zostanie uruchomiony.
Myślałem o wywołanie Launch()
w osobnym wątku w dziale SetUp
moich testów, ale potem muszę trochę hack umieścić w Thread.Sleep(1000)
aby upewnić się, że testy nie są uruchamiane przed Launch()
zakończył. Nie mogę użyć właściwej synchronizacji (jak ManualResetEvent
), ponieważ Launch()
nigdy nie wróci. Bieżący kod jest:
private Launcher launcher;
private Thread launchThread;
[TestFixtureSetUp]
public void SetUp()
{
launcher = new Launcher();
launchThread = new Thread(o => launcher.Launch());
launchThread.Start();
Thread.Sleep(2500); //yuck!!
}
[TestFixtureTearDown]
public void TearDown()
{
if (launcher != null)
{
launcher.Dispose(); //ouch
}
}
Idealnie co szukam jest non-blocking sposobem uruchomienia usługi i programowy sposób zatrzymując go ponownie, aby umieścić w moim TearDown
. W tej chwili mój TearDown
po prostu uruchamia program uruchamiający (więc TearDown
dosłownie rozrywa go!).
Czy ktoś ma doświadczenie w testowaniu usług Topshelf w ten sposób? Mogę to zrobić stosunkowo łatwo przy użyciu standardu ServiceHost
, ale wolę jawną konfigurację i łatwość instalacji w Topshelf.
link jest uszkodzony – SteveC
@ SteveC już nie. Link jest dostępny w tej chwili. – dotnetguy