[英]Integration Tests With Topshelf to Start a C# Windows Service
我正在使用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啟動我的服務。 問題是,一旦您在Topshelf主機上調用Run()
,代碼便會阻塞,因此我的測試代碼將永遠不會運行。
我想呼吁的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
確實將其TearDown
了!)。
有沒有人有過以這種方式測試Topshelf服務的經驗? 我可以使用標准ServiceHost
相對輕松地完成上述操作,但是我更喜歡在Topshelf中進行顯式配置和易於安裝。
https://github.com/Topshelf/Topshelf/blob/v2.3/src/Topshelf/Config/Builders/RunBuilder.cs#L113我想這就是您想要的。 AfterStartingService
可用於從其他線程設置ManualResetEvent
。
現在,這可能對您來說可行,但是這感覺太過復雜了,僅通過部署到開發/登台並對系統進行煙霧測試即可得到驗證。 但是,如果不進一步了解您的環境,那將是不可能的。
今天,我遇到了同樣的問題,我選擇將服務實例化和交互與實際的Topshelf托管隔離開(這只不過是在您的情況下使用Ninject解決服務)。
亞當·羅傑(Adam Rodger)有一個公平的觀點,在快速瀏覽了ConsoleRunHost
的Run方法ConsoleRunHost
,它實際上將掛起以等待ManualResetEvent
並且直到該服務終止之前都不會將控件退還給您。
在您的地方,要對冒煙/回歸測試進行編碼,只需將內核和模塊放入您的SetUp
方法中,解析服務,進行測試並將其放置在TearDown
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.