在没有构造函数注入的情况下使用 ILogger<T>
Using ILogger<T> without constructor injection
我的注册和构造函数设置如下,通过 Microsoft.Extensions.Logging 使用日志记录,
public MyService(ILogger<MyService> logger) {}
不过,我想做的是在 Startup.cs 中使用 services.AddSingleton()
以避免使用构造函数注入。原因是否则在测试服务时将需要修改所有单元测试以模拟记录器。
我相信有一种方法可以在 ServiceCollection 中注册 ILogger 的特定实例,但我无法整理出所需的语法。
谢谢!
- 在单元测试中你不应该使用 DI 容器。
- 如果是,那么您正在编写集成测试,而不是单元测试。
- 在单元测试中,一般来说,测试的安排部分应该set-up你的SUT通过直接调用SUT的构造函数和passing-in test/mock/stub 其依赖项的版本。
- 在单元测试中,理想情况下,您应该提供整个 testing-implementation 的整个
Microsoft.Extensions.Logging.ILoggerProvider
接口(以及相关的 类),这将允许您断言特定的日志输出消息已写入,或将 ILogger
和 ILogger<T>
输出重定向到您的测试自己的输出。
- 不幸的是,这不是 in-box(和 Microsoft won't release their own),但是有许多流行的库用于此:
- 或者,如果您的测试不关心
ILogger
用法 and/or 如果您不想将 SUT 自己的日志输出写入测试输出,then use 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:
// [...]
}
我的注册和构造函数设置如下,通过 Microsoft.Extensions.Logging 使用日志记录,
public MyService(ILogger<MyService> logger) {}
不过,我想做的是在 Startup.cs 中使用 services.AddSingleton()
以避免使用构造函数注入。原因是否则在测试服务时将需要修改所有单元测试以模拟记录器。
我相信有一种方法可以在 ServiceCollection 中注册 ILogger 的特定实例,但我无法整理出所需的语法。
谢谢!
- 在单元测试中你不应该使用 DI 容器。
- 如果是,那么您正在编写集成测试,而不是单元测试。
- 在单元测试中,一般来说,测试的安排部分应该set-up你的SUT通过直接调用SUT的构造函数和passing-in test/mock/stub 其依赖项的版本。
- 在单元测试中,理想情况下,您应该提供整个 testing-implementation 的整个
Microsoft.Extensions.Logging.ILoggerProvider
接口(以及相关的 类),这将允许您断言特定的日志输出消息已写入,或将ILogger
和ILogger<T>
输出重定向到您的测试自己的输出。- 不幸的是,这不是 in-box(和 Microsoft won't release their own),但是有许多流行的库用于此:
- 或者,如果您的测试不关心
ILogger
用法 and/or 如果您不想将 SUT 自己的日志输出写入测试输出,then useNullLoggerFactory
或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:
// [...]
}