单元测试用例单独运行正常但批量执行失败求助
单元测试单独运行正常,批量运行失败的排查求助
我有一个单元测试用例,单独运行时正常,但所有测试一起运行时失败。尝试过添加Thread.Sleep()、将方法改为同步调用,都没有效果。
运行错误信息
Assert.Equal() Failure: Values differ
Expected: 2
Actual: 4
失败的测试代码
[Fact] public async Task Should_Trigger_PublishLocationWac_Function() { //Arrange PrepareData(out List<LocationWac> locationWacData, out SkuAndWac skuAndWac); Arrange(locationWacData); //Act var result = await _handler.RunAsync(skuAndWac, _mockContext.Object); //Assert Assert.Equal(locationWacData.Count, result.TotalDocuments); Assert.Equal(locationWacData.Count, result.TotalPublished); } private void Arrange(List<LocationWac> oneWacData, bool IsPublishedFailed = false, bool isException = false) { Environment.SetEnvironmentVariable(ConfigConstants.BatchSize, oneWacData.Count.ToString()); _mockloggerFactory.Setup(p => p.CreateLogger(It.IsAny<string>())).Returns(_mockLogger.Object); _mockServiceProvider.Setup(p => p.GetService(It.IsAny<Type>())).Returns(_mockloggerFactory.Object); _mockContext.Setup(p => p.InstanceServices).Returns(_mockServiceProvider.Object); var cursorMock = new Mock<IAsyncCursor<LocationWac>>(); cursorMock.SetupSequence(x => x.MoveNext(It.IsAny<CancellationToken>())) .Returns(true) .Returns(false); cursorMock.SetupSequence(x => x.MoveNextAsync(It.IsAny<CancellationToken>())) .ReturnsAsync(true) .ReturnsAsync(false); cursorMock.SetupGet(x => x.Current).Returns(oneWacData); if (isException) { _mockLocationWacRepository.Setup(x => x.GetCollection().FindAsync(It.IsAny<FilterDefinition<LocationWac>>(), It.IsAny<FindOptions<LocationWac, LocationWac>>(), default)) .ThrowsAsync(new Exception("Test exception")); } else { _mockLocationWacRepository.Setup(x => x.GetCollection().FindAsync(It.IsAny<FilterDefinition<LocationWac>>(), It.IsAny<FindOptions<LocationWac, LocationWac>>(), default)) .ReturnsAsync(cursorMock.Object); } if (IsPublishedFailed) { _mockMessageProducer.Setup(x => x.Produce(It.IsAny<List<string>>(), It.IsAny<string>())) .ReturnsAsync(0); } else { _mockMessageProducer.Setup(x => x.Produce(It.IsAny<List<string>>(), It.IsAny<string>())) .ReturnsAsync(oneWacData.Count); } } private static void PrepareData(out List<LocationWac> locationWacData, out SkuAndWac skuAndWac) { locationWacData = [ new LocationWac { DataPartitionKey = "sain1", Sku = "sku1", Sain = "sain1", WacPerUnit = 1.0m, LastModifiedDate = DateTime.Now, VariancePercent = 0.1m, ProductGroup = "Food" }, new LocationWac { DataPartitionKey = "sain2", Sku = "sku2", Sain = "sain2", WacPerUnit = 1.0m, LastModifiedDate = DateTime.Now, VariancePercent = 0.1m, ProductGroup = "Food" } ]; skuAndWac = new SkuAndWac { Sain = "sain1", Wac = 1.0m }; }
可成功运行的测试用例
[Fact] public async Task RunAsync_Should_Log_BusinessException_WhenPublishingFails() { //Arrange PrepareData(out List<LocationWac> locationWacData, out SkuAndWac skuAndWac); Arrange(locationWacData, true); //Act var result = await _handler.RunAsync(skuAndWac, _mockContext.Object); // Assert Assert.Equal(locationWacData.Count, result.TotalDocuments); Assert.Equal(0, result.TotalPublished); _mockErrorHandlingHelper.Verify(x => x.InsertErrorLogAsync(It.IsAny<ServiceNowErrorLog>()), Times.Once); }
排查方向与解决方案
全局环境变量污染
Environment.SetEnvironmentVariable是全局生效的,多个测试运行时会互相覆盖BatchSize的值。解决方案:- 在测试初始化时保存原有环境变量值,测试结束后恢复
- 改用测试专用的配置注入方式,避免修改全局环境变量
Mock对象未隔离
类级别的Mock实例(如_mockLocationWacRepository)会在多个测试中共享状态,之前的Setup会累积生效。解决方案:- 在每个测试的
[SetUp]方法中重新创建Mock实例 - 测试结束后调用
mock.Reset()清除所有Setup
- 在每个测试的
测试上下文未隔离
如果_handler、_mockContext是类级别的共享实例,前一个测试的状态会残留到下一个测试。解决方案:- 在
[SetUp]中重新创建所有核心测试对象,确保每个测试都有干净的上下文
- 在
验证Mock调用次数
在失败的测试中添加Mock方法的调用次数验证,确认是否被意外多次调用:_mockLocationWacRepository.Verify(x => x.GetCollection().FindAsync(It.IsAny<FilterDefinition<LocationWac>>(), It.IsAny<FindOptions<LocationWac, LocationWac>>(), default), Times.Once);
内容的提问来源于stack exchange,提问作者Juhi Shrivastava
相关产品推荐
相关产品推荐

