Sto usando Topshelf per ospitare un servizio Windows scritto in C# e ora voglio scrivere alcuni test di integrazione. Il mio codice di inizializzazione si svolge in una classe lanciatore come il seguente:Test di integrazione con Topshelf per avviare un servizio 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;
}
}
}
voglio scrivere alcuni test di integrazione per assicurarsi che log4net e Ninject avere istituito correttamente e TopShelf lancia il mio servizio. Il problema è che, una volta chiamato Run()
sull'host di Topshelf, il codice si blocca e il codice di test non viene mai eseguito.
ho pensato di chiamare Launch()
in un thread separato nella sezione SetUp
dei miei test, ma poi ho bisogno di un po 'di hack per mettere in un Thread.Sleep(1000)
per assicurarsi che i test non vengono eseguiti prima Launch()
ha finito. Non riesco a utilizzare una sincronizzazione adeguata su di esso (ad esempio ManualResetEvent
) perché Launch()
non restituisce mai. Il codice attuale è:
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
}
}
Idealmente quello che sto cercando è un modo non-blocking del lancio del servizio e un modo programmatico di fermarsi di nuovo per mettere nel mio TearDown
. Al momento il mio TearDown
dispone solo del launcher (quindi lo TearDown
lo strappa letteralmente!).
Qualcuno ha esperienza nel test dei servizi di Topshelf in questo modo? Posso fare quanto sopra facilmente usando lo standard ServiceHost
ma preferisco di gran lunga la configurazione esplicita e la facilità di installazione in Topshelf.
Il collegamento è interrotto – SteveC
@ SteveC non più. Il link è accessibile al momento. – dotnetguy