首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Moq模拟Microsoft.Extensions.Logging

如何使用Moq模拟Microsoft.Extensions.Logging
EN

Stack Overflow用户
提问于 2019-03-17 00:15:24
回答 2查看 1.2K关注 0票数 5

我目前正在尝试让以下代码在运行时成功:

代码语言:javascript
复制
public delegate void LogDelegate(LogLevel logLevel, EventId eventId, object state, Exception exception, Func<object, Exception, string> formatter);

public abstract class LoggingTestBase
{
    private Mock<ILogger> _mockLogger;

    public ILogger Setup(LogDelegate logCallback)
    {
        _mockLogger = new Mock<ILogger>(MockBehavior.Strict);
        _mockLogger.Setup(logger => logger.Log(
                It.IsAny<LogLevel>(),
                It.IsAny<EventId>(),
                It.IsAny<object>(),
                It.IsAny<Exception>(),
                It.IsAny<Func<object, Exception, string>>()))
            .Callback(logCallback);
        return _mockLogger.Object;
    }
}

问题是,一旦我运行测试,我就会得到一个MockException,因为被调用的方法是我显然没有设置的通用ILogger.Log<FormattedLogValues>(...)

阅读existing answer to this和Moq文档后,我得出的结论是,我可能只需要使用如上所示的正确类型参数模拟泛型方法。

在这里,我偶然遇到了下一个问题,它将我的想法带到了尽头:

在当前版本的Microsoft.Extensions.Logging中,FormattedLogValues不再是公共的,而是内部的(遵循this PR),这使得无法模拟最终被调用的泛型方法。

有没有人成功解决了这个问题?多么?

EN

回答 2

Stack Overflow用户

发布于 2019-10-02 00:50:21

我也有类似的问题。我只想验证是否调用了对LogInformation的调用。根据这个-> https://github.com/aspnet/Extensions/issues/1319,它可能应该由Moq..

但是,最后有一个建议,您可以使用It.IsAnyType而不是object。对于您来说,这可能是这样的:

代码语言:javascript
复制
_mockLogger.Setup(logger => logger.Log(
            It.IsAny<LogLevel>(),
            It.IsAny<EventId>(),
            It.IsAny<It.IsAnyType>(),
            It.IsAny<Exception>(),
            (Func<It.IsAnyType, Exception, string>) It.IsAny<object>()))
        .Callback(logCallback);

我一直没能让它工作,但也许这会把你推向正确的方向?

票数 1
EN

Stack Overflow用户

发布于 2021-03-31 17:32:18

这里解释和解决的验证解决方案:

https://adamstorr.azurewebsites.net/blog/mocking-ilogger-with-moqthe Github source is here.

我的个人环境不需要验证,只需要关于日志调用的Moq。因此,我将代码修改为:

代码语言:javascript
复制
namespace my.xTests
{
    public static class VerifyLoggingUtil
    {
        public static Mock<ILogger<T>> SetupLogging<T>(
            this Mock<ILogger<T>> logger
        )
        {
            Func<object, Type, bool> state = (v, t) => true;
            logger.Setup(
                x => x.Log(
                    It.Is<LogLevel>(l => true),
                    It.IsAny<EventId>(),
                    It.Is<It.IsAnyType>((v, t) => state(v, t)),
                    It.IsAny<Exception>(),
                    It.Is<Func<It.IsAnyType, Exception, string>>((v, t) => true)));
            return logger;
        }
    }
}

在我的xUnit测试设置中:

代码语言:javascript
复制
namespace my.xTests
{
     public class myTests{
        private Mock<Microsoft.Extensions.Logging.ILogger<sFTPAzFn.Logging>> moqlog;
        private MockRepository mockRepository;
        public myTests(){
            this.mockRepository = new MockRepository(MockBehavior.Strict);
            moqlog = this.mockRepository.Create<Microsoft.Extensions.Logging.ILogger<MyLoggingClass>>();
        }
        private IInterfaceUnderTest CreateService(){
             var moqlogobject = moqlog.SetupLogging<MyLoggingClass>().Object;
             return new ClassUnderTest(moqlogobject);
        }
     }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55198845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档