wpf - 为什么我的模拟记录器显示为已调用但也没有?
问题描述
我第一次尝试在 WPF 应用程序中进行模拟。我正在测试的代码是 MVVM ViewModel 方法的一部分,如下所示:
try
{
var airframesForRegistration = this.UnitOfWork.Airframes.GetAirframesForRegistration(this.SearchRegistration);
this.currentAirframes = new ObservableCollection<Airframe>(airframesForRegistration);
}
catch (Exception ex)
{
this.logger.Error($"Could not access the database", ex);
throw;
}
我想测试一下
- 错误被写入记录器服务并且
- 抛出异常。
为此,我使用了 XUnit 和 Moq:
[Fact]
public void GetAirframesForSearchRegistration_DBAccessFail()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IUnitOfWork>()
.Setup(x => x.Airframes.GetAirframesForRegistration("AAAA"))
.Throws(new DataException());
string message = "Could not access the database";
DataException exception = new DataException();
mock.Mock<ILog>()
.Setup(x => x.Error(message, exception));
var afrvm = mock.Create<AirframesForRegistrationViewModel>();
afrvm.SearchRegistration = "AAAA";
Assert.Throws<DataException>(() => afrvm.GetAirframesForSearchRegistration());
mock.Mock<ILog>()
.Verify(x => x.Error(message, exception), Times.Exactly(1));
}
测试因此失败:
Message: Moq.MockException :
Expected invocation on the mock exactly 1 times, but was 0 times: x => x.Error("Could not access the database'", System.Data.DataException: Data Exception.)
Configured setups:
ILog x => x.Error("Could not access the database", System.Data.DataException: Data Exception.)
Performed invocations:
ILog.Warn("No Operators found in the database")
ILog.Warn("No airframe statuses found in the database")
ILog.Error("Could not access the database", System.Data.DataException: Data Exception.
at Moq.MethodCall.Execute(Invocation invocation) in C:\projects\moq4\src\Moq\MethodCall.cs:line 120
(注意额外的 ILog 警告出现在 ViewModel 的其他地方,我期待这些警告)。
问题
这意味着调用了错误日志记录,但测试失败了,因为它被调用了零次!如何设置 Moq 和 XUnit 以正确测试这种情况?
解决方案
记录器参数的设置是问题所在。
抛出的实例和预期的实例不同意味着它们在调用模拟时不会匹配。
模拟工作单元正在抛出一个新异常。不是你期待的那个。
[Fact]
public void GetAirframesForSearchRegistration_DBAccessFail() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
DataException exception = new DataException();
mock.Mock<IUnitOfWork>()
.Setup(x => x.Airframes.GetAirframesForRegistration("AAAA"))
.Throws(exception);
string message = "Could not access the database";
mock.Mock<ILog>()
.Setup(x => x.Error(message, exception));
var afrvm = mock.Create<AirframesForRegistrationViewModel>();
afrvm.SearchRegistration = "AAAA";
//Act
Action act = () => afrvm.GetAirframesForSearchRegistration();
//Assert
Assert.Throws<DataException>(act);
mock.Mock<ILog>()
.Verify(x => x.Error(message, exception), Times.Exactly(1));
}
}
对于更宽松的期望,您可以使用It.IsAny<>
参数匹配器
[Fact]
public void GetAirframesForSearchRegistration_DBAccessFail() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
mock.Mock<IUnitOfWork>()
.Setup(x => x.Airframes.GetAirframesForRegistration("AAAA"))
.Throws(new DataException());
string message = "Could not access the database";
mock.Mock<ILog>()
.Setup(x => x.Error(message, It.IsAny<DataException>()));
var afrvm = mock.Create<AirframesForRegistrationViewModel>();
afrvm.SearchRegistration = "AAAA";
//Act
Action act = () => afrvm.GetAirframesForSearchRegistration();
//Assert
Assert.Throws<DataException>(act);
mock.Mock<ILog>()
.Verify(x => x.Error(message, It.IsAny<DataException>()), Times.Exactly(1));
}
}
推荐阅读
- swiftui - 带有相关动画的 SwiftUI 过渡
- c# - 为什么 Polly AsyncCircuitBreakerPolicy 会断开 TPL 数据流块之间的链接?
- spring-boot - REST API - 使用 ID 列表删除
- javascript - Expo“yarn androd”命令在加载 javascript 包后未加载 App.js
- python - Python双双引号没有被替换
- flutter - 如何以编程方式打开键盘文本字段
- python - 布尔索引器脚本没有错误但不起作用
- javascript - 通过 Node.js 托管本地服务器未按预期工作
- php - 太多时PHP关闭连接
- angular - Stripe V3 RedirectToCheckout 定义