Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用iLogger提供程序进行单元测试_C#_Asp.net Core_.net Core_Asp.net Core 3.1 - Fatal编程技术网

C# 使用iLogger提供程序进行单元测试

C# 使用iLogger提供程序进行单元测试,c#,asp.net-core,.net-core,asp.net-core-3.1,C#,Asp.net Core,.net Core,Asp.net Core 3.1,我的单元测试设置中有如下代码: IServiceCollection services = new ServiceCollection(); services.AddSingleton<IDependency, Dependency>(); services.AddLogging(); services.RemoveAll<ILoggerProvider>(); services.AddSingleton<ILoggerProvider, MyCustomProvi

我的单元测试设置中有如下代码:

IServiceCollection services = new ServiceCollection();
services.AddSingleton<IDependency, Dependency>();
services.AddLogging();
services.RemoveAll<ILoggerProvider>();
services.AddSingleton<ILoggerProvider, MyCustomProvider>(provider =>
{
    var myDependency = provider.GetService<IDependency>();
    return new MyCustomProvider(myDependency );
});
var serviceProvider = services.BuildServiceProvider();

var logger = serviceProvider.GetService<ILogger>();

不知何故,这是在不指明任何提供者的情况下完成的。我希望在我的单元测试中也能做到这一点。(只需使用我的自定义提供程序。)

NET CORE测试我正在这样做:

在测试类的构造函数中(或进行DI映射的位置)

公共类UnitTest1
{
公共IConfigurationRoot配置{get;set;}
私有只读IDisponabilitaService_disponabilitaService;
公共单元测试1()
{
var services=newservicecolection();
配置=新的ConfigurationBuilder()
.SetBasePath(Path.Combine(Path.directoryseportorchar.ToString(),“directory”,“Kalliope_CTI”,“backend”,“KalliopeCTITestProject”))
.AddJsonFile(“testconfig.json”,可选:false,reloadOnChange:true)
.Build();
services.AddSingleton();//<--此处尝试设置NullLoggerFactory
var serviceProvider=服务
.AddOptions()
.BuildServiceProvider();
}
////你的测试方法
}

希望它能帮助你

它可能是在黑暗中拍摄的,但您可以尝试将您的
iLogger提供程序添加到
iLogger工厂


var loggerFactory=serviceProvider.GetService示例中的
logger
变量为
null
的原因是
ILogger
实际上没有注册为服务。如果查看
AddLogging
的源代码,您可以看到它只注册了
ILogger
ILogger工厂
。如果您曾经尝试通过.NET Core DI接受
ILogger
而不是
ILogger
,您将遇到以下异常*:

System.InvalidOperationException:'无法解析类型的服务 “Microsoft.Extensions.Logging.ILogger”正在尝试激活 “你的服务”

基于此,您的测试代码是有缺陷的,因为您从一开始就不会收到
ILogger
。要查看您的代码是否实际工作,请修改您的测试代码,使其检索
ILogger
。变量的结果将为非null,并且将命中提供程序构造函数中设置的断点:

// Get*Required*Service won't throw
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
以下内容现在可以使用您的自定义提供程序:

var loggerA = serviceProvider.GetRequiredService<ILogger<Program>>();
var loggerB = serviceProvider.GetRequiredService<ILogger>();
var loggerA=serviceProvider.GetRequiredService();
var loggerB=serviceProvider.GetRequiredService();
我有自己的自定义提供程序/工厂/记录器,用于按照与您相同的注册模式将xUnit的
ITestOutputHelper
注入自定义记录器,因此我根据个人经验知道这是可行的。但我还测试了您的特定代码是否正常工作(模拟我自己的
IDependency
)——执行上述代码,并在
MyCustomProvider
的构造函数中设置断点,然后点击服务注册。此外,如果我将记录器注入到一个类中,它也会被命中(正如预期的那样)

您的评论“不知何故,这是在没有指明任何提供商的情况下完成的”是错误的,因为您确实注册了提供商!但是,即使在清除了所有提供程序并且没有添加新的提供程序的场景中,您仍然会得到一个非空的记录器。这是因为
LoggerFactory
只是循环遍历每个提供程序,围绕它们构建一个新的记录器包装器。如果没有提供程序,那么您基本上会得到一个无操作记录器

*这是不幸的,因为一些工具(如R#)会建议将参数转换为基本类型
ILogger
,这会破坏DI


**默认类别名称是必需的,因为没有要传递给
ILoggerFactory.CreateLogger
的泛型类型参数。对于通用的
ILogger
来说,类别名称总是
T
名称的一个变体——但我们显然没有在非通用版本中得到这一点。如果非要我猜的话,这可能就是为什么默认情况下他们不注册
ILogger
的实现。

hi您是否尝试过类似services.AddSingleton()的东西;
// Get*Required*Service won't throw
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
services.AddSingleton<ILoggerProvider, MyCustomProvider>(); // no need for lambda
services.AddSingleton<ILogger>(sp => 
  sp.GetService<ILoggerFactory>().CreateLogger("Default")
);
var loggerA = serviceProvider.GetRequiredService<ILogger<Program>>();
var loggerB = serviceProvider.GetRequiredService<ILogger>();