在C#中,使用ILogger对静态方法进行单元测试的静态方法ILoggerFactory为空

如何解决在C#中,使用ILogger对静态方法进行单元测试的静态方法ILoggerFactory为空

所有人

我正在尝试对代码进行单元测试,但是我无法使ILoggerFactory工作

这是我的单元测试代码(可能不正确):

using NUnit.Framework;
using Microsoft.Extensions.Logging;
using System.Reflection;
using Moq;
using System;
using MyProgramVIP.Bots.Presenter;
using MyProgramVIP.Bots.Model;
using MyProgramVIP.Bots.Utils;

namespace MyProgramVIPTest
{
    public class TestsExample
    {
        [SetUp]
        public void Setup() {
            
        }

        [Test]
        public void TestExample1()
        {
            //Mocks
            var mockLogger = new Mock<ILogger<TicketPresenter>>();
            mockLogger.Setup(
                m => m.Log(
                    LogLevel.Information,It.IsAny<EventId>(),It.IsAny<object>(),It.IsAny<Exception>(),It.IsAny<Func<object,Exception,string>>()));

            var mockLoggerFactory = new Mock<ILoggerFactory>();
            mockLoggerFactory.Setup(x => x.CreateLogger(It.IsAny<string>())).Returns(() => mockLogger.Object);

            //Construción del modelo necesario para la prueba
            ConversationData conversationData = new ConversationData();
            conversationData.ticket = new Ticket();
            conversationData.response = new Response();

            //Invocación del método a probar
            TicketPresenter.getPutTicketMessage(conversationData);

            //Comprobación del funcionamineto
            Assert.AreEqual("ticketType",conversationData.response.cardIdResponse);
        }
    }
}

这是我要测试的类的代码(我只剩下失败的代码行)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using MyProgramVIP.Bots.Interactor.Services;
using MyProgramVIP.Bots.Model;
using MyProgramVIP.Bots.Utils;

namespace MyProgramVIP.Bots.Presenter
{
    public class TicketPresenter
    {
        private static ILogger _logger = UtilsVIP.ApplicationLogging.CreateLogger(MethodBase.GetCurrentMethod().DeclaringType.Name);

        /// <summary>
        /// Función getPutTicketMessage: encargada de comenzar con el flujo de poner un ticket.
        /// </summary>
        /// <param name="conversationData"></param>
        public static void getPutTicketMessage(ConversationData conversationData)
        {
            try
            {
                //Here it crash.
                _logger.LogInformation("INIT getPutTicketMessage");

                //Code..........

                //Never gets here.
                _logger.LogInformation("ENDED getPutTicketMessage");
            }
            catch (Exception ex)
            {
                //Here it crash too.
                _logger.LogError("EXCEPTION getPutTicketMessage" + ex.ToString());
            }
        }
}

这是错误所在的帮助类的代码:

using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using MyProgramVIP.Bots.Model;
using MyProgramVIP.Bots.Model.Elements;

namespace MyProgramVIP.Bots.Utils
{
    public class UtilsVIP
    {
        private static ILogger _logger = ApplicationLogging.CreateLogger("ILogger");

        //Other funtions...

        public static class ApplicationLogging
        {
            public static ILoggerFactory LoggerFactory { get; set; }
            public static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
            //Here LoggerFactory is null.
            public static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger("VIPLog: " + categoryName);

        }

        //Other funtions...
    }
}

就在它运行的行上:

LoggerFactory.CreateLogger("VIPLog: " + categoryName);

LoggerFactory为空。

我已经在互联网上做了大量研究,但是所有这些都会导致非静态的班级信息。

如果重要的话,这是Botframework项目。

任何帮助将不胜感激。

谢谢。

解决方法

非常感谢@ChetanRanpariya的评论,我的问题的答案非常简单:

keywords
hummm asd yes
blow com nope
rest hiya mouse
wow good com

只需添加以下内容:

using NUnit.Framework;
using Microsoft.Extensions.Logging;
using System.Reflection;
using Moq;
using System;
using MyProgramVIP.Bots.Presenter;
using MyProgramVIP.Bots.Model;
using MyProgramVIP.Bots.Utils;

namespace MyProgramVIPTest
{
    public class TestsExample
    {
        [SetUp]
        public void Setup() {
            
        }

        [Test]
        public void TestExample1()
        {
            //Mocks
            var mockLogger = new Mock<ILogger<TicketPresenter>>();
            mockLogger.Setup(
                m => m.Log(
                    LogLevel.Information,It.IsAny<EventId>(),It.IsAny<object>(),It.IsAny<Exception>(),It.IsAny<Func<object,Exception,string>>()));

            var mockLoggerFactory = new Mock<ILoggerFactory>();
            mockLoggerFactory.Setup(x => x.CreateLogger(It.IsAny<string>())).Returns(() => mockLogger.Object);

            //Just add this,I guess is replacing the objet with the mock.
            UtilsVIP.ApplicationLogging.LoggerFactory = mockLoggerFactory.Object;
            
            //Construción del modelo necesario para la prueba
            ConversationData conversationData = new ConversationData();
            conversationData.ticket = new Ticket();
            conversationData.response = new Response();

            //Invocación del método a probar
            TicketPresenter.getPutTicketMessage(conversationData);

            //Comprobación del funcionamineto
            Assert.AreEqual("ticketType",conversationData.response.cardIdResponse);
        }
    }
}

感谢您的帮助。

,

在此示例如何验证使用Moq在ILogger上调用了日志。

 _loggerMock.Verify
        (
            l => l.Log
            (
                //Check the severity level
                LogLevel.Error,//This may or may not be relevant to your scenario
                It.IsAny<EventId>(),//This is the magical Moq code that exposes internal log processing from the extension methods
                It.Is<It.IsAnyType>((state,t) =>
                    //This confirms that the correct log message was sent to the logger. {OriginalFormat} should match the value passed to the logger
                    //Note: messages should be retrieved from a service that will probably store the strings in a resource file
                    CheckValue(state,LogTest.ErrorMessage,"{OriginalFormat}") &&
                    //This confirms that an argument with a key of "recordId" was sent with the correct value
                    //In Application Insights,this will turn up in Custom Dimensions
                    CheckValue(state,recordId,nameof(recordId))
            ),//Confirm the exception type
            It.IsAny<NotImplementedException>(),//Accept any valid Func here. The Func is specified by the extension methods
            (Func<It.IsAnyType,string>)It.IsAny<object>()),//Make sure the message was logged the correct number of times
            Times.Exactly(1)
        );

    private static bool CheckValue(object state,object expectedValue,string key)
    {
        var keyValuePairList = (IReadOnlyList<KeyValuePair<string,object>>)state;

        var actualValue = keyValuePairList.First(kvp => string.Compare(kvp.Key,key,StringComparison.Ordinal) == 0).Value;

        return expectedValue.Equals(actualValue);
    }

this article中有更多上下文。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-