c# - 为什么我的单元测试使用 Moq 的 Verify() 是不确定的?
问题描述
我们使用 Moq 4 进行单元测试,特别是控制器单元测试。我们正在使用 Moq 的 Verify() 方法来确保记录了错误。问题是测试可以通过,但在下一次运行时失败。
我们使用 Serilog 作为我们的记录器。
Action 方法看起来像
public IActionResult Index(){
try{
var data = _repository.GetData();
return View(data);
}catch(Exception e){
Log.Error(e.Message);
}
}
所以单元测试正在使用
_mockLogger.Verify(x=> x.Write(LogEventLevel.Error,It.IsAny<string>()));
mockLogger
在测试的构造函数中设置,如
var _mockLogger = new Mock<Serilog.ILogger>();
Log.Logger = _mockLogger.Object;
//...
并且存储库被模拟以在调用时抛出异常。
当它失败时,我们会收到错误消息
“Moq.MoqException 预期在 Mock 上至少调用一次,但从未执行过
x=>x.Write(LogEventLevel.Error,It.IsAny<string>())
”
有任何想法吗?
解决方案
从发布的代码中无法完全看出问题所在。我很欣赏为此制作 MCVE 的难度。所以我要猜两个。
猜测 1:我怀疑您的问题的原因是static
您的代码中使用了 s,特别是与记录器有关。
我怀疑正在发生的事情是其他测试(未在帖子中显示)也在修改/定义记录器的行为方式,并且由于记录器是静态的,因此测试相互干扰。
尝试重新设计代码,以便使用 serilog 的 ILogger 接口将日志记录功能的实例依赖注入到被测类中,将其存储在只读字段中,并在您想要记录时使用它。
猜想 2:根据帖子中“...在测试的构造函数中设置”的部分,您没有说(或标记)您正在使用哪个测试框架;但是我用过的少数人更喜欢你在属性方法中而不是在测试的构造函数中做这种事情。例如,NUnit 有 OneTimeSetUp(在该类中的任何测试运行之前)、SetUp(在该类中的每个测试运行之前)、TearDown(在该类中的每个测试运行之后)、OneTimeTearDown(在所有测试之后在那个类中运行)。您的测试的构造函数可能以您不期望的顺序被调用,并且您的测试框架不支持该顺序;而属性化方法序列由框架保证。
推荐阅读
- python - 在块外部或内部编写脚本标签?
- rust - 如何在 Rust 中访问系统定时器中断
- java - 为什么我的 ImageButtons 不能为我的滑动益智游戏随机播放?
- excel - 我们如何在没有 MSCOMCT2.OCX 文件的情况下使用 datepicker?
- c++ - Cmake找不到提升窗口
- javascript - 在 *ngfor(Angular) 中插入具有特定样式属性的动态元素
- google-maps - ionic 4 地图在浏览器中工作但在 Andriod 设备中不工作
- javascript - 用户可以在加载页面之前使用开发人员工具控制台取消绑定页面加载事件处理程序吗?
- python-3.x - 一次访问 RDD 中的 200 个文件 pyspark
- operators - 数学等价于双右移和 AND 运算符?