在.net核心Ihostedservice上编写单元测试的良好实践是什么?

时间:2019-02-11 09:44:06

标签: unit-testing microservices background-process asp.net-core-hosted-services

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

虽然我可以将backgroundtask作为应用程序运行,并使用日志,数据库检查以及其他工具的帮助进行测试,但是是否需要进行单元测试才能测试backgroundtask?如果是这样,如何将任务注册为具有依赖项的服务并触发start和stop方法来断言实际与预期的关系?赞赏一些基于计时器的.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);
        }

1 个答案:

答案 0 :(得分: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 模拟任何其他依赖项,并在您想要验证的任何其他内容上断言。