You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Moq设置异步方法抛异常后调用验证随机失败是什么原因

单元测试异步异常流验证随机失败问题

我正在编写异常流单元测试,在代码中设置异步函数抛出异常,后续验证该函数被调用1次时,测试结果随机波动,有时提示无任何调用,有时符合预期正常通过,请问该问题是什么原因导致的?

测试代码

[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");
}

更新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;
    }
}

更新2:问题根因

问题已排查,根因为其他数据初始化类存在竞态条件,因此问题随机出现。


内容的提问来源于stack exchange,提问作者MC LinkTimeError

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:06:01