Использование ILogger<T> без внедрения конструктора

У меня есть настройка регистрации и конструктора для использования ведения журнала через Microsoft.Extensions.Logging следующим образом:

public MyService(ILogger<MyService> logger) {}

Однако я хотел бы использовать services.AddSingleton()в моем Startup.cs, чтобы избежать использования внедрения конструктора. Причина в том, что в противном случае потребуется изменить все модульные тесты, чтобы имитировать регистратор при тестировании службы.
Я считаю, что есть способ зарегистрировать конкретный экземпляр ILogger в ServiceCollection, но я не могу разобраться с необходимым синтаксисом.

Спасибо!

1 ответ

  • В модульных тестах вы не должны использовать DI-контейнер.
    • Если да, то вы пишете интеграционный тест, а не модульный тест.
  • В модульных тестах, вообще говоря, организационная часть теста должна настроить вашу SUT, напрямую вызывая конструктор SUT и передавая версии test/mock/stub его зависимостей.
  • В модульных тестах в идеале вы должны предоставить полную тестовую реализацию всего Microsoft.Extensions.Logging.ILoggerProviderинтерфейс (и связанные классы), который позволит вам утверждать, что определенные выходные сообщения журнала были записаны, или перенаправлять и выводить на собственный вывод вашего теста.
  • В качестве альтернативы, если ваши тесты не связаны с утверждением ILoggerиспользования и/или если вы не хотите, чтобы собственный вывод журнала вашей SUT записывался в ваш тестовый вывод, используйте NullLoggerFactoryили же NullLogger<T>.Instanceв разделе аранжировки , чтобы создать заглушку ILogger<T>это ничего не делает.

Как это:

      using Microsoft.Extensions.Logging.Abstractions;

// [...]

[Fact]
public void MyService_should_do_something()
{
    // Arrange:

    IArbitraryDependency dep         = new StubArbitraryDependency();
#if FULL_MOON_TONIGHT
    ILogger<MyService>   nullLogger  = NullLoggerFactory.Instance.CreateLogger<MyService>();
#else
    ILogger<MyService>   nullLogger  = NullLogger<MyService>.Instance();
#endif

    MyService systemUnderTest = new MyService(
        arbitraryDependency: dep,
        logger             : nullLogger
    );

    // Act:

    systemUnderTest.DoSomething();

    // Assert:
    // [...]
}
Другие вопросы по тегам