如何为我的后台服务编写单元测试? [英] How can I write unit test for my background service?

查看:31
本文介绍了如何为我的后台服务编写单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 .NET Core 中的 HostBuilder(而不是 WebHost!).

I'm working with the HostBuilder in .NET Core (not the WebHost !).

我的应用程序中运行了一个托管服务,该服务覆盖了后台服务的 ExecuteAsync/StopAsync 方法,我想对其进行单元测试.

I have one Hosted Service running in my application that overrides the ExecuteAsync/StopAsync methods of the background Service and I want to unit test it.

这是我的托管服务:

public class DeviceToCloudMessageHostedService : BackgroundService
{
    private readonly IDeviceToCloudMessageService _deviceToCloudMessageService;
    private readonly AppConfig _appConfig;

    public DeviceToCloudMessageHostedService(IDeviceToCloudMessageService deviceToCloudMessageService, IOptionsMonitor<AppConfig> appConfig)
    {
        _deviceToCloudMessageService = deviceToCloudMessageService;
        _appConfig = appConfig.CurrentValue;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            await _deviceToCloudMessageService.DoStuff(stoppingToken);
            await Task.Delay(_appConfig.Parameter1, stoppingToken);
        }
    }
    
    public override Task StopAsync(CancellationToken cancellationToken)
    {
        Log.Information("Task Cancelled");
        _deviceToCloudMessageService.EndStuff();
        return base.StopAsync(cancellationToken);
    }

我已经找到了这篇文章:.NET Core 中托管服务的集成测试

I already found this post: Integration Test for Hosted Service in .NET Core

但它是为 QueuedBackgroundService 解释的,我真的不知道我是否可以用同样的方式测试我的.

But it's explained for a QueuedBackgroundService and I don't really know if I can test mine the same way.

我只想知道我的代码是否被执行.我不想要任何具体的结果.你知道我如何测试它吗?

I just want to know if my code is executed. I don't want any specific result. Do you have any idea of how I can test it?

推荐答案

您仍然应该能够遵循与链接答案类似的格式.

You should still be able to follow a similar format as the linked answer.

模拟依赖项并注入它们,调用被测方法并断言预期的行为.

Mock the dependencies and inject them, invoke the methods under test and assert the expected behavior.

以下使用 Moq 来模拟依赖项,并使用 ServiceCollection 来完成注入依赖项的繁重工作.

The following uses Moq to mock the dependencies along with ServiceCollection to do the heavy lifting of injecting the dependencies.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

[TestMethod]
public async Task DeviceToCloudMessageHostedService_Should_DoStuff() {
    //Arrange
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<IHostedService, DeviceToCloudMessageHostedService>();
    //mock the dependencies for injection
    services.AddSingleton(Mock.Of<IDeviceToCloudMessageService>(_ =>
        _.DoStuff(It.IsAny<CancellationToken>()) == Task.CompletedTask
    ));
    services.AddSingleton(Mock.Of<IOptionsMonitor<AppConfig>>(_ =>
        _.CurrentValue == Mock.Of<AppConfig>(c => 
            c.Parameter1 == TimeSpan.FromMilliseconds(1000)
        )
    ));
    var serviceProvider = services.BuildServiceProvider();
    var hostedService = serviceProvider.GetService<IHostedService>();

    //Act
    await hostedService.StartAsync(CancellationToken.None);
    await Task.Delay(1000);//Give some time to invoke the methods under test
    await hostedService.StopAsync(CancellationToken.None);

    //Assert
    var deviceToCloudMessageService = serviceProvider
        .GetRequiredService<IDeviceToCloudMessageService>();
    //extracting mock to do verifications
    var mock = Mock.Get(deviceToCloudMessageService);
    //assert expected behavior
    mock.Verify(_ => _.DoStuff(It.IsAny<CancellationToken>()), Times.AtLeastOnce);
    mock.Verify(_ => _.EndStuff(), Times.AtLeastOnce());
}

现在,理想情况下,这将算作测试框架代码,因为您基本上是在测试 BackgroundService 在运行时的行为是否符合预期,但它应该足以说明如何单独测试此类服务

Now, ideally this would count as testing framework code since you are basically testing that a BackgroundService behaves as expected when run, but it should demonstrate enough about how one would test such a service in isolation

这篇关于如何为我的后台服务编写单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆