web-dev-qa-db-fra.com

Test d'intégration pour le service hébergé .Net-Core`

J'ai un service hébergé QueueTask (le nouveau service d'arrière-plan de .Net-Core) que je voudrais tester. Mon service queuedHosted ressemble à ceci:

public QueuedHostedService(IServiceProvider serviceProvider, IBackgroundTaskQueue taskQueue, ILoggerFactory loggerFactory)
{
    TaskQueue = taskQueue;
    _logger = loggerFactory.CreateLogger<QueuedHostedService>();
    _serviceProvider = serviceProvider;
}

protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
    using (var scope = _serviceProvider.CreateScope())
    {
        while (false == stoppingToken.IsCancellationRequested)
        {
            var workItem = await TaskQueue.DequeueAsync(stoppingToken);
            try
            {
                await workItem(scope.ServiceProvider, stoppingToken);
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, $"Error occurred executing {nameof(workItem)}.");
            }
        }
    }
}

Il lit simplement les tâches de la file d'attente et les exécute à mesure qu'elles arrivent. J'ai déjà vérifié que le service hébergé fonctionne en production. J'ai écrit un test comme ceci:

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task()
{
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

    await Task.Delay(10000);
    Assert.IsTrue(isExecuted);
}

Cependant, mon rappel n'est jamais touché. Comment puis-je exécuter ma tâche sur le service d'arrière-plan?

Modifier

J'imitais le démarrage et je supposais que le service d'arrière-plan fonctionnerait, mais apparemment, mon service n'est jamais démarré,

Comment le service hébergé est-il normalisé à partir de .Net-Core?

15
johnny 5

Les services hébergés sont démarrés par le cadre dans le cadre du processus de démarrage de WebHost

// Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);

Source

via le HostedServiceExecutor qui prendrait une collection de tous les IHostedService enregistrés, les énumérerait et les démarrerait à son tour

public HostedServiceExecutor(ILogger<HostedServiceExecutor> logger, IEnumerable<IHostedService> services)
{
    _logger = logger;
    _services = services;
}

public async Task StartAsync(CancellationToken token)
{
    try
    {
        await ExecuteAsync(service => service.StartAsync(token));
    }
    catch (Exception ex)
    {
        _logger.ApplicationError(LoggerEventIds.HostedServiceStartException, "An error occurred starting the application", ex);
    }
}

Source

Mais comme vous testez le service hébergé seul, vous devez agir comme cadre et démarrer le service vous-même.

[TestMethod]
public async Task Verify_Hosted_Service_Executes_Task() {
    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
    services.AddHostedService<QueuedHostedService>();
    services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
    var serviceProvider = services.BuildServiceProvider();

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

    var backgroundQueue = serviceProvider.GetService<IBackgroundTaskQueue>();

    await service.StartAsync(CancellationToken.None);

    var isExecuted = false;
    backgroundQueue.QueueBackgroundWorkItem(async (sp, ct) => {
        isExecuted = true;
    });

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

    await service.StopAsync(CancellationToken.None);
}
11
Nkosi