Moq -函数设置抛出async不算作函数调用



我正在写一个不愉快的流单元测试。

在我的代码中,我设置了一个函数来抛出async,然后验证该函数被调用了一次。此场景不定期地失败或成功,因为有时它显示没有进行调用,有时函数被调用一次(按计划)。

你知道为什么吗?

如果需要更多的代码请告诉我。谢谢!

测试:

[Fact]
public async Task ContainerScan_ControllerTest_ErrorFlow()
{
//Given
TestsRegistrar.ContainerClient.Reset();
TestsRegistrar.ContainerClient.Setup(x => x.MyAsyncFunc(It.IsAny<Guid>(), It.IsAny<List<ContainerScanRecord>>())).ThrowsAsync(new Exception("bad stuff happened"));
var controller = new ContainersRiskGeneratorController(TestsRegistrar.ContainersGenerator, new Mock<IExtendedLogger>().Object, new Mock<IExtendedLoggerEnricher>().Object);
var scanId = Guid.NewGuid();

//When
var result = await controller.SomeUpperFuncthatCallsMyAsyncFunc(scanId, new RiskGenerator.Dto.V3.ContainersScanRequest
{
ContainerRecords = new List<RiskGenerator.Dto.V3.SomeDto>
{
new RiskGenerator.Dto.V3.SomeDto{
params here
}
}
});

//Then
result.Should().BeEmpty();
TestsRegistrar.ContainerClient.Verify(x => x.MyAsyncFunc(It.IsAny<Guid>(), It.IsAny<List<ContainerScanRecord>>()), Times.Once, "Container Engine should be called once");
}

UDPATE # 1:增加了调用函数

SomeUpperFuncthatCallsMyAsyncFunc的代码:

[HttpPost("someUrl/{scanId:Guid?}")]
[DisableRequestSizeLimit]
public async Task<IReadOnlyCollection<SomeDto>> SomeUpperFuncthatCallsMyAsyncFunc(Guid? _, [FromBody] ContainersScanRequest request)
{
try
{
Ensure.NotNull(nameof(request), request);
_extendedLoggerEnricher.Enrich(new { request.ScanId });
_logger.Info("GenerateContainerRiskAsync called", new { request.ScanId });
var response =
await _riskGenerator.TheCallingFuncToMyAsyncFunc(
request.ScanId,
request.ContainerRecords
.Where(x=> !string.IsNullOrEmpty(x.DockerFilePath))
.Select(ContainerScanRiskRecordDto.ToContainerScanRecord).ToList())
.ConfigureAwait(false);
return response.Select(VulnerableContainerScanRecordDto.ToContainerScanVulnerablerRecord).ToArray();
}
catch (Exception exception)
{
_logger.Error("Exception thrown during generate GenerateContainerRiskAsync", exception, new { request.ScanId });
StatusCode((int)HttpStatusCode.InternalServerError);
return new List<SomeDto>();
}
}

和直接调用MyAsyncFunc的函数:

public async Task<List<(ContainerScanRecord record, ImageVulnerabilitiesDto vulnerabilities)>> TheCallingFuncToMyAsyncFunc(Guid id, IReadOnlyCollection<ContainerScanRecord> containerRecords)
{
try
{
return await
_containerEngineClient.MyAsyncFunc(id, containerRecords).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error($"[{id}] Could not generate GenerateContainerRiskDataAsync: {exception.Message}", exception);
throw;
}
}

UDPATE # 2我明白了!嗯…事实证明,这是与初始化数据的其他类的一个令人讨厌的竞争条件。这就是为什么它是随机发生的。很抱歉让你这么忙,谢谢你的时间。

我最近发现,当函数抛出时,它的调用不能被计数。这就是为什么你可能会遇到这样的问题。

您可以做的是验证logger是否记录了一个错误(与断言您的方法被调用的方式相同)。