gpt4 book ai didi

c# - 如何为我的后台服务编写单元测试?

转载 作者:行者123 更新时间:2023-11-30 14:44:55 27 4
gpt4 key购买 nike

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

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

这是我的托管服务:

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);
}

我已经找到这篇文章:Integration Test for Hosted Service in .NET Core

但是它针对 QueuedBackgroundService 进行了解释,我真的不知道我是否可以用同样的方式测试我的。

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

最佳答案

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

模拟依赖项并注入(inject)它们,调用被测方法并断言预期行为。

以下使用 Moq 模拟依赖项以及 ServiceCollection 来完成注入(inject)依赖项的繁重工作。

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 在运行时是否按预期运行,但它应该足以证明人们如何单独测试此类服务

关于c# - 如何为我的后台服务编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56644654/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com