How can i write unit test for my background service?

て烟熏妆下的殇ゞ 提交于 2020-03-18 06:31:05

问题


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

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

Here is my HostedService:

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

I already found this post Integration Test For Hosted Service .Net-Core` 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 ? Thanks a lot.


回答1:


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.

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

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

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



来源:https://stackoverflow.com/questions/56644654/how-can-i-write-unit-test-for-my-background-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!