Moq和Microsoft.Extensions.Logging.ILogger单元测试在Microsoft.Extensions.Logging.Abstractions更新后失败

编程入门 行业动态 更新时间:2024-10-25 23:35:35
本文介绍了Moq和Microsoft.Extensions.Logging.ILogger单元测试在Microsoft.Extensions.Logging.Abstractions更新后失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

将Microsoft.Extensions.Logging.Abstractions从Version = 2.0.0.0更新到Version = 3.1.1.0后,我的某些单元测试失败.

Some of my unit tests are failing after updating Microsoft.Extensions.Logging.Abstractions from Version=2.0.0.0 to Version=3.1.1.0.

我模拟了一个ILogger:

I have an ILogger mocked as so:

var loggerMock = new Mock<ILogger<BillingEventProcessor>>(); loggerMock.Setup(l => l.Log( It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<IReadOnlyList<KeyValuePair<string, object>>>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>()));

已经建立了一个验证对Log()的调用的单元:

And a unit that verifies a call to Log() has been made:

logger.Verify(l => l.Log( It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<IReadOnlyList<KeyValuePair<string, object>>>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>()) );

在更新之前, IReadOnlyList< KeyValuePair<字符串,对象>> 类型的类型为 FormattedLogValues .

Prior to updating, the IReadOnlyList<KeyValuePair<string, object>> type was of type FormattedLogValues.

在v2中,FormattedLogValues是一个公共类,但在v3.1.1中,FormattedLogValues是一个内部只读结构.这种变化似乎与测试失败有关.

In v2, FormattedLogValues was a public class but in v3.1.1, FormattedLogValues is an internal readonly struct. This change appears to be related to the test failures.

我尝试将It.IsAny用作第3个参数,而不是IReadOnlyList或FormattedLogValues,但我对此没有任何运气.

I've tried using It.IsAny for that 3rd parameter instead of the IReadOnlyList or FormattedLogValues but I didn't have any luck with that.

任何人都知道如何更改此测试代码以使测试通过吗?从调试信息中可以看到,对Log方法的调用已按预期进行,只是无法弄清楚如何使用内部readonly struct参数正确设置这些模拟.

Anyone know how I can alter this test code to make the test pass? I can see from debugging info that a call to the Log method is made as expected, I just can't figure out how to set up these mocks correctly with the internal readonly struct parameter.

这是一个.NET Core 2.2项目.

This is a .NET Core 2.2 project.

推荐答案

FormattedLogValues 更改为Internal,这有点不方便.使用Moq的常见解决方案是使用 It.IsAnyType :

FormattedLogValues in .NET Core 3.* was changed to internal which is a bit inconvenient. The common solution using Moq is to use It.IsAnyType:

loggerMock.Verify(l => l.Log( It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), (Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Once);

我通常希望从验证中获得更多信息,至少检查一下消息:

I usually like to get a bit more out of my verify, checking the message at least:

loggerMock.Verify(l => l.Log( It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.Is<It.IsAnyType>((o, t) => ((IReadOnlyList<KeyValuePair<string, object>>)o).Last().Value.ToString().Equals(message)), It.IsAny<Exception>(), (Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Once);

作为旁注,您提到您正在设置记录器模拟.我想不起来我明确设置了记录器模拟程序的时间,因为通常没有任何必要.

As a side note you mentioned you're setting up the logger mock. I can't think of a time where I've explicitly set up a logger mock as there usually isn't any need to.

最后,如果您像我一样经常这样做,通常在无头的黑盒子中,请考虑contrib库 Moq.Contrib.ExpressionBuilders.Logging 可以解决上述所有问题,并提供流畅的构建器来轻松创建验证表达式.免责声明,我是作者.

Finally if you're doing this a lot like I do, usually in headless black boxes, consider the contrib library Moq.Contrib.ExpressionBuilders.Logging which takes care of all of the above and provides a fluent builder to easily create the verify expression. Disclaimer, I am the author.

更多推荐

Moq和Microsoft.Extensions.Logging.ILogger单元测试在Microsoft.Extensions.Logging.Abstra

本文发布于:2023-11-15 04:08:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1591011.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单元测试   Extensions   Microsoft   Moq   Abstractions

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!