Интеграционный тест с 2 фоновыми сервисами - PullRequest
0 голосов
/ 16 июня 2020

У меня есть основной проект dot net, в котором я пытаюсь написать интеграционный тест между двумя моими BackgroundServices.

Ниже мой текущий xUnit тест:

[Fact]
public async Task FileWatcherIntegration()
{
    IServiceCollection services = new ServiceCollection();
    services.AddHostedService<FileWatcherService>();
    services.AddHostedService<FailedTradesWorker>();
    services.AddSingleton(fileWatcherOptions);
    services.AddSingleton<ILogger<FileWatcherService>>(logger);

    var serviceProvider = services.BuildServiceProvider();


    var fileWatcher = serviceProvider.GetService<IHostedService>() as FileWatcherService; 
    var tradeWorker = serviceProvider.GetService<IHostedService>() as FailedTradesWorker;

    // act
    await tradeWorker.StartAsync(CancellationToken.None);
    await fileWatcher.StartAsync(CancellationToken.None);

    /* Ommited */


    await tradeWorker.StopAsync(CancellationToken.None);
    await fileWatcher.StopAsync(CancellationToken.None);

    // assert
    Assert.True(File.Exists(fileWatcherOptions.DestinationPathAndName));
}

Мой тест не проходит на линии var fileWatcher = serviceProvider.GetService<IHostedService>() as FileWatcherService; с сообщением об ошибке: Unable to resolve service for type

Что такое правильный способ настроить мои службы для этого теста?

Ответы [ 2 ]

0 голосов
/ 16 июня 2020

Разрешите все зарегистрированные сервисные узлы, используя GetServices<IHostedService>()

Это вернет IEnumerable<IHostedService>. Оттуда остается только запустить службы.

Следующий подход получает все задачи запуска и остановки и использует Task.WhenAll для их ожидания

[Fact]
public async Task FileWatcherIntegration() {
    // Arrange
    IServiceCollection services = new ServiceCollection();
    services.AddHostedService<FileWatcherService>();
    services.AddHostedService<FailedTradesWorker>();
    services.AddSingleton(fileWatcherOptions);
    services.AddSingleton<ILogger<FileWatcherService>>(logger);

    IServiceProvider serviceProvider = services.BuildServiceProvider();

    IEnumerable<IHostedService> hosts = serviceProvider.GetServices<IHostedService>();

    // Act
    await Task.WhenAll(hosts.Select(host => host.StartAsync(CancellationToken.None)));

    /* Ommited */

    await Task.WhenAll(hosts.Select(host => host.StopAsync(CancellationToken.None)));

    // Assert
    Assert.True(File.Exists(fileWatcherOptions.DestinationPathAndName));
}
0 голосов
/ 16 июня 2020

Это выглядит странно:

var serviceProvider = services.BuildServiceProvider();
var tradeServiceProdiver = tradeServices.BuildServiceProvider();

var fileWatcher = serviceProvider.GetService<IHostedService>() as FileWatcherService; 
var tradeWorker = serviceProvider.GetService<IHostedService>() as FailedTradesWorker;

Я бы использовал одного поставщика услуг и получил бы услуги по их типу:

var serviceProvider = services.BuildServiceProvider();

var fileWatcher = serviceProvider.GetService<FileWatcherService>();
var tradeWorker = serviceProvider.GetService<FailedTradesWorker>();

Или я бы создал интерфейсы, которые Я мог бы использовать вот так:

public interface IFileWatcherService : IHostedService
{
   ...
}

public interface IFailedTradesWorker : IHostedService
{
   ...
}

services.AddHostedService<IFileWatcherService, FileWatcherService>();
services.AddHostedService<IFailedTradesWorker, FailedTradesWorker>();

var fileWatcher = serviceProvider.GetService<FileWatcherService>();
var tradeWorker = serviceProvider.GetService<FailedTradesWorker>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...