【发布时间】:2022-06-10 18:23:36
【问题描述】:
我正在尝试 Moq 同步过程,但我遇到了一个特定部分的问题。
在我尝试最小起订量的方法中,我执行以下操作:
public SyncManager(IPubHttpClient pubClient, ILogger<SyncManager> logger)
{
_pubHttpClient = pubClient;
_logger = logger;
}
public async Task Sync()
{
// get logs
foreach (var log in logs)
{
syncStatus = await GetAndSendCost(log);
}
}
private async Task<SyncStatus> GetAndSendCost(Log log)
{
var cost = new Cost
{
CostCode = log.CostCode,
CostName = log.Description,
Active = log.Active
};
await _pubHttpClient.Push(EventModel { Cost = cost, MessageType = log.Type.GetDescription() });
return SyncStatus.Success;
}
GetAndSendCost 方法被另一个方法调用(称为 Sync,在SyncManager 中)。
我设置的测试是这样的:
public readonly Mock<IPubHttpClient> _pubClientMock = new();
var mockedCost = new Cost { Active = CostStatus.Active, CostCode = "0000", CostName = "UNIT TEST" };
_pubClientMock.Setup(p => p.Push(It.Is<EventModel>(x => x.Cost == mockedCost && x.MessageType == "CREATE"))).Returns(Task.CompletedTask).Verifiable();
var syncManager = new SyncManager(_pubClientMock.Object, Mock.Of<ILogger<SyncManager>>());
await syncManager.Sync();
_pubClientMock.Verify(p => p.Push(It.Is<EventModel>(
x => x.Cost.CostName == mockedCost.CostName
&& x.Cost.CostCode == mockedCost.CostCode
&& x.Cost.Active == mockedCost.Active
&& x.MessageType == "CREATE")));
当我运行这个测试时,每段代码都被正确调用,在调试时我看到 EventModel object 正在使用正确的值创建。
但是在我的测试中,当我调用_pubClientMock.Verify(); 时,我得到了System.NullReferenceException:
x.Cost 似乎在这里为 NULL。
知道为什么这个属性会是 NULL 或者我在这里做错了什么吗?
谢谢!
【问题讨论】:
-
x.Cost == mockedCost在你的模拟谓词中检查引用相等,而不是值。 -
@ChrisPickford 有没有办法解决这个问题?如果在 .Setup() 我做
x => x.Cost.CostCode == mockedCost.CostCode然后我在我的await _pubHttpClient.Push(EventModel { Cost = cost, MessageType = log.Type.GetDescription() });中得到一个空引用异常。如果我稍后在单元测试_pubClientMock.Verify(p => p.Push(It.Is<AnalyticalCombinationEvent>(x => x.Cost.CostCode == mockedCost.CostCode...中执行 .Verify(),我也会得到一个空引用异常。