Topshelfを使用して C# で記述された Windows サービスをホストしていますが、いくつかの統合テストを記述したいと考えています。私の初期化コードは、次のようなランチャー クラスに保持されます。
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;
}
}
}
log4net と Ninject が適切にセットアップされ、Topshelf がサービスを開始することを確認するために、いくつかの統合テストを作成したいと考えています。Run()
問題は、 Topshelf ホストを呼び出すとコードがブロックされるため、テスト コードが実行されないことです。
Launch()
テストのセクションで別のスレッドを呼び出すことを考えましたが、終了する前にテストが実行されないようにするためSetUp
に少しハックする必要があります。が返されないため、( のような) 適切な同期を使用できません。現在のコードは次のとおりです。Thread.Sleep(1000)
Launch()
ManualResetEvent
Launch()
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
}
}
理想的には、私が探しているのは、サービスを起動する非ブロッキングの方法と、サービスを再度停止してTearDown
. 現時点でTearDown
は、ランチャーを破棄するだけです (つまり、TearDown
文字通り破棄します!)。
この方法で Topshelf サービスをテストした経験のある人はいますか? 標準を使用して上記のことを比較的簡単に行うことができますがServiceHost
、明示的な構成と Topshelf でのインストールの容易さを好みます。