4

我有一个由.NET Core 中的托管服务实现的后台任务。这个类的逻辑很少:

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
}

如何对DoWork方法中的逻辑进行单元测试?问题是托管服务是由框架管理的,我不知道如何隔离这个类。

4

2 回答 2

6

不知道你说的隔离班级是什么意思。这些并不神奇。ASP.NET Core 只是实例化具有任何所需依赖项的类,然后调用StartAsync,然后StopAsync在应用程序关闭时调用。没有什么是您不能自己手动完成的。

换句话说,要对其进行单元测试,您将模拟依赖项、实例化类并调用StartAsync它。但是,我认为整体托管服务更适合集成测试。您可以将任何实际工作分解到一个对单元测试更简单的帮助程序类中,然后简单地对服务运行集成测试以确保它通常可以执行它应该执行的操作。

于 2019-09-03T15:26:53.560 回答
0

使用以下命令从依赖注入容器中检索托管服务:

. . .
services.AddHostedService<IndexingService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
IndexingService indexingService = serviceProvider.GetService<IHostedService>() as IndexingService;
. . .
于 2022-03-03T00:11:15.667 回答