Что такое хорошая практика для написания юнит-теста на.net core Ihostedservice?

У меня есть фоновая задача, инициированная при запуске.net core 2.0, наследуется от backgroundservice, реализуя StartAsync, StopAsync и ExecuteAsync. Эта задача состоит в том, чтобы периодически обновлять некоторые данные в таблице базы данных на основе некоторой бизнес-логики.

Хотя я могу запускать backgroundtask как приложение и тестировать с помощью журналов, db check и с помощью других инструментов, может ли модульное тестирование быть необходимым для тестирования backgroundtask? Если да, то как зарегистрировать задачу как службу с зависимостями и запустить методы start и stop, чтобы подтвердить фактическое и ожидаемое значение? Оцените некоторые базовые примеры модульных тестов при тестировании на основе таймера.net core ihostedservice backgroundtask.

Вот мой основной тестовый запуск только для образца, но еще не завершен. Сказав это, это всего лишь мысль, но не точный рабочий тест. Вот что нужно, чтобы помочь сообществу. Можно также добавить еще несколько утверждений, например, 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 ответ

Вот как я обычно это делаю. Вы упомянули, что собираетесь в базу данных обновить некоторые данные, поэтому я предполагаю, что вы ожидаете, что это зависит от 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 и Assert, для чего-либо еще, что хотите проверить.

Другие вопросы по тегам