public class IndexingService : IHostedService, IDisposable
{
private readonly int indexingFrequency;
private readonly IIndexService indexService;
private readonly ILogger logger;
private bool isRunning;
private Timer timer;
public IndexingService(ILogger<IndexingService> logger, IIndexService indexService, IndexingSettings indexingSettings)
{
this.logger = logger;
this.indexService = indexService;
this.indexingFrequency = indexingSettings.IndexingFrequency;
}
public void Dispose()
{
this.timer?.Dispose();
}
public Task StartAsync(CancellationToken cancellationToken)
{
this.timer = new Timer(this.DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(this.indexingFrequency));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
this.timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
private void DoWork(object state)
{
if (this.isRunning)
{
// Log
return;
}
try
{
this.isRunning = true;
this.indexService.IndexAll();
}
catch (Exception e)
{
// Log, The background task should never throw.
}
finally
{
this.isRunning = false;
}
}
}
我的Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedService<IndexingService>();
services.AddTransient<IIndexService, IndexService>();
// 'IndexingSettings' is read from appsetting and registered as singleton
}
我如何单位测试logic
DoWork
方法?问题是托管服务是由框架管理的,我不知道如何隔离此类。
确定您对隔离班的意思是什么。这些不是神奇的。 ASP.NET Core只需使用任何必需的依赖项实例化类,然后调用
StartAsync
,然后在应用程序关闭时进行StopAsync
StartAsync
。但是,我认为总体托管服务是整合测试的更好候选人。您可以将任何真实工作分为助手类,该类别对单位测试更为简单,然后简单地对服务进行集成测试,以确保它通常可以做到它应该做的。将托管服务从依赖项注入容器中撤回以下内容:
. . .
services.AddHostedService<IndexingService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
IndexingService indexingService = serviceProvider.GetService<IHostedService>() as IndexingService;
. . .
BackgroundService
我想单位测试。 这个MS测试正常工作!
[TestMethod()]
public async Task ExecuteAsync_TaskQueue()
{
// Arrange
var cancellationToken = new CancellationToken();
await _sut.StartAsync(cancellationToken);
// Act
_sut.TaskQueue.QueueBackgroundWorkItem(DoSomething);
await _sut.StopAsync(cancellationToken);
// Assert
Assert.AreEqual(_codeExecuted, true);
}
public Task DoSomething(CancellationToken cancellationToken)
{
_codeExecuted = true;
return Task.CompletedTask;
}
StartAsync
。 然后,在您的应用程序寿命中的某个时刻,背景作业将执行(在我的情况下)。 您可以在
QueueBackgroundWorkItem
中放置一个断点,并看到它实际上被称为。
在这种方式中,您可以单位测试“背景服务”,而无需测试任何其他应用程序逻辑。
google测试托管服务的首先结果让我来到这里,而chatgpt太愚蠢了。 我需要为此编写测试,因为我使用了添加多个服务的扩展方法。
当接受的答案是方式,这就是您快速获得背景服务的方式:
DoSomething