集成测试与Topshelf启动C#Windows服务

Ada*_*ger 6 c# integration-testing unit-testing windows-services topshelf

我正在使用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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想编写一些集成测试,以确保正确设置log4net和Ninject,并且Topshelf启动我的服务.问题是,一旦你调用Run()Topshelf主机,代码就会阻塞,所以我的测试代码永远不会运行.

我想Launch()在SetUp我的测试部分中调用一个单独的线程但是我需要一些黑客来Thread.Sleep(1000)确保测试在Launch()完成之前不运行.我不能在它上面使用正确的同步(比如a 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
    }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,我正在寻找的是一种非阻塞的启动服务的方式,以及一种程序化的方式来再次阻止它来放入我的服务TearDown.此刻,我TearDown刚刚处理了发射器(所以TearDown真的把它撕下来!).

有没有人有过以这种方式测试Topshelf服务的经验?我可以使用标准相对容易地完成上述操作,ServiceHost但我更喜欢Topshelf中的显式配置和易于安装.

Tra*_*vis 2

https://github.com/Topshelf/Topshelf/blob/v2.3/src/Topshelf/Config/Builders/RunBuilder.cs#L113我认为这就是你想要的。AfterStartingService可以用来ManualResetEvent从不同的线程设置 a 。

现在这可能适合您,但这感觉过于复杂,只需部署到开发/登台并对系统进行冒烟测试即可进行验证。但是,如果没有更多地了解您的环境,这可能是不可能的。