5

我有一个在 .net core 2.0 启动时启动的后台任务,继承自 backgroundservice,实现 StartAsync、StopAsync 和 ExecuteAsync。这个任务是根据一些业务逻辑定期更新数据库表中的一些数据。

虽然我可以将后台任务作为应用程序运行并使用日志、数据库检查和其他工具进行测试,但单元测试对于测试后台任务是否是必要的?如果是这样,如何将任务注册为具有依赖关系的服务并触发启动和停止方法来断言实际与预期?在测试基于计时器的 .net 核心 ihostedservice 后台任务时欣赏一些基本的示例单元测试方法。

这是我的基本测试开始,仅用于示例,但尚未完成。话虽如此,这只是一个想法,而不是确切的工作测试。这是需要社区帮助的内容。还可以添加更多断言,即 Assert.Verify()?

  [Fact]
        public async void Run_background_task_success()
        {
            //Arrange
            IServiceCollection services = new ServiceCollection();

            services.AddHostedService<BackgroundManagerTask>();

            var serviceProvider = services.BuildServiceProvider();

            var service = serviceProvider.GetService<IHostedService>() as BackgroundManagerTask;

            var isExecuted = false;
            if(await service.StartAsync(CancellationToken.None))
{
isExecuted = true;
}

            await Task.Delay(10000);
            Assert.True(isExecuted);

            await service.StopAsync(CancellationToken.None);
        }
4

1 回答 1

0

这是我通常的做法。你提到你要去数据库更新一些数据,所以我假设你期望这是一个依赖BackgroundManager

[Fact]
public void BackgroundManagerUpdatingDataTest()
{
    // Arrange
    Mock<IDataAccess> dbMock = new Mock<IDataAccess>();
    dbMock.Setup(x => x.UpdateSomethingInDB(It.IsAny<BusinessObject>())).Returns(1); // One row updated from the DML in UpdateSomethingInDB from the BusinessObject
    
    BackgroundManager sut = new BackgroundManager(dbMock.Object); // System under test.

    // Act
    await sut.StartAsync(CancellationToken.None);
    await Task.Delay(500); // Give the test some time to execute.
    await sut.StopAsync(CancellationToken.None); // Stop the Background Service.

    // Assert
    dbMock.Verify(x => x.UpdateSomethingInDB(It.IsAny<BusinessObject>()), Times.Exactly(1));
}

上面,我们通过模拟数据访问调用并验证它被调用了一次,从而清楚地测试了对数据库的更新。

您当然可以使用Moq和 Assert 对您想要验证的任何其他内容进行 Mock 任何其他依赖项。

于 2021-02-10T00:57:20.813 回答