.NET Core 中托管服务的集成测试
Integration Test for Hosted Service in .NET Core
我有一个 QueueTask 托管服务(.NET Core 的新后台服务),我想测试一下。我的 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)}.");
}
}
}
}
它只是从队列中读取任务并在它们进入时执行它们。我已经验证托管服务正在生产中运行。我像这样为它写了一个测试:
[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);
}
但是,我的回调从未被命中。如何让我的任务在后台服务上执行?
编辑
我在模仿启动,并假设我的后台服务可以正常工作,
但显然我的服务从未启动。
托管服务如何从.NET Core正常启动?
托管服务由框架作为 WebHost 启动过程的一部分启动
// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);
通过 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);
}
}
但由于您是自行测试托管服务,因此您必须充当框架并自行启动服务。
[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);
}
我有一个 QueueTask 托管服务(.NET Core 的新后台服务),我想测试一下。我的 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)}.");
}
}
}
}
它只是从队列中读取任务并在它们进入时执行它们。我已经验证托管服务正在生产中运行。我像这样为它写了一个测试:
[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);
}
但是,我的回调从未被命中。如何让我的任务在后台服务上执行?
编辑
我在模仿启动,并假设我的后台服务可以正常工作, 但显然我的服务从未启动。
托管服务如何从.NET Core正常启动?
托管服务由框架作为 WebHost 启动过程的一部分启动
// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);
通过 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);
}
}
但由于您是自行测试托管服务,因此您必须充当框架并自行启动服务。
[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);
}