1

我有我的注册和构造函数设置来通过 Microsoft.Extensions.Logging 使用日志记录,如下所示,

public MyService(ILogger<MyService> logger) {}

不过,我想做的是services.AddSingleton()在我的 Startup.cs 中使用以避免使用构造函数注入。原因是它需要在测试服务时修改所有单元测试以模拟记录器。
我相信有一种方法可以在 ServiceCollection 中注册 ILogger 的特定实例,但我无法理清所需的语法。

谢谢!

4

1 回答 1

5
  • 在单元测试中,您不应该使用 DI 容器。
    • 如果是,那么您正在编写集成测试,而不是单元测试。
  • 在单元测试中,一般来说,测试的安排部分应该通过直接调用 SUT 的构造函数并传入其依赖项的 test/mock/stub 版本来设置您的 SUT。
  • 在单元测试中,理想情况下,您应该提供整个接口(和相关类)的完整测试实现Microsoft.Extensions.Logging.ILoggerProvider,这将允许您断言已写入特定的日志输出消息,或者重定向ILoggerILogger<T>输出到您的测试自己的输出。
  • 或者,如果您的测试不关心断言ILogger使用和/或如果您不希望将 SUT 自己的日志输出写入测试输出,则使用NullLoggerFactoryorNullLogger<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:
    // [...]
}
于 2022-02-12T18:07:04.643 回答