在没有<T>构造函数注入的情况下使用 ILogger



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

public MyService(ILogger<MyService> logger) {}

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

谢谢!

  • 在单元测试中,您不应该使用DI容器。
    • 如果是,那么您正在编写集成测试,而不是单元测试
  • 一般来说,在单元测试中,测试的arrange部分应该通过直接调用SUT的构造函数并传入其依赖关系的test/mok/stub版本来设置SUT
  • 在单元测试中,理想情况下,您应该提供整个Microsoft.Extensions.Logging.ILoggerProvider接口(和相关类(的完整测试实现,这将允许您断言特定的日志输出消息已写入,或者将ILoggerILogger<T>输出重定向到测试自己的输出。
    • 不幸的是,这不是现成的(微软也不会发布自己的(,但有很多流行的库:
      • https://github.com/martincostello/xunit-logging
      • https://github.com/alefranz/MELT
  • 或者,如果您的测试不关心断言ILogger的使用,和/或如果您不希望SUT自己的日志输出写入测试输出,那么在arrange部分中使用NullLoggerFactoryNullLogger<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:
// [...]
}

相关内容

  • 没有找到相关文章

最新更新