简体   繁体   English

.NET Core 中托管服务的集成测试

[英]Integration Test for Hosted Service in .NET Core

I have a QueueTask Hosted service (.NET Core's new background service) that I'd like to test.我有一个要测试的 QueueTask 托管服务(.NET Core 的新后台服务)。 My queuedHosted service looks like so:我的 queuedHosted 服务如下所示:

public QueuedHostedService(IServiceProvider serviceProvider, IBackgroundTaskQueue taskQueue, ILoggerFactory loggerFactory)
{
    TaskQueue = taskQueue;
    _logger = loggerFactory.CreateLogger<QueuedHostedService>();
    _serviceProvider = serviceProvider;
}

protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
    using (var scope = _serviceProvider.CreateScope())
    {
        while (false == stoppingToken.IsCancellationRequested)
        {
            var workItem = await TaskQueue.DequeueAsync(stoppingToken);
            try
            {
                await workItem(scope.ServiceProvider, stoppingToken);
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, $"Error occurred executing {nameof(workItem)}.");
            }
        }
    }
}

It just reads tasks from the queue and executes them as they come in. I've already verified that the Hosted Service is working in Production.它只是从队列中读取任务并在它们进入时执行它们。我已经验证托管服务正在生产中工作。 I wrote a test for it like so:我为它写了一个测试,如下所示:

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task()
{
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

    await Task.Delay(10000);
    Assert.IsTrue(isExecuted);
}

However, my callback is never hit.但是,我的回调从未被击中。 How can I get my task to execute on the Background Service?如何让我的任务在后台服务上执行?

Edit编辑

I was mimicking the startup, and assumed my background service would just work, but apparently my service is never started.我正在模仿启动,并假设我的后台服务可以正常工作,但显然我的服务从未启动。

How is the Hosted Service normally Started from .NET Core? Hosted Service 通常是如何从 .NET Core 启动的?

Hosted services are started by the framework as part of the WebHost's start process托管服务由框架作为 WebHost 启动过程的一部分启动

// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);

Source 来源

via the HostedServiceExecutor which would take a collection of all the registered IHostedService , enumerate them and start them in turn通过HostedServiceExecutor它将收集所有已注册的IHostedService ,枚举它们并依次启动它们

public HostedServiceExecutor(ILogger<HostedServiceExecutor> logger, IEnumerable<IHostedService> services)
{
    _logger = logger;
    _services = services;
}

public async Task StartAsync(CancellationToken token)
{
    try
    {
        await ExecuteAsync(service => service.StartAsync(token));
    }
    catch (Exception ex)
    {
        _logger.ApplicationError(LoggerEventIds.HostedServiceStartException, "An error occurred starting the application", ex);
    }
}

Source 来源

But since you are testing the hosted service on its own, you have to act as the framework and start the service yourself.但是,由于您自己测试托管服务,因此您必须充当框架并自己启动服务。

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task() {
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

    var service = serviceProvider.GetService<IHostedService>() as QueuedHostedService;

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    await service.StartAsync(CancellationToken.None);

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

    await Task.Delay(10000);
    Assert.IsTrue(isExecuted);

    await service.StopAsync(CancellationToken.None);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM