How can i write unit test for my background service?

后端 未结 1 1964
一向
一向 2021-01-02 17:47

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 Meth

相关标签:
1条回答
  • 2021-01-02 17:53

    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

    0 讨论(0)
提交回复
热议问题