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
相关产品推荐
相关产品推荐

