外部服务方法Mock失效,调用后返回Null问题求助
排查Mock AssignOrderReserve方法返回Null的原因
问题背景
测试中对ISupplyReservesClient的AssignOrderReserve方法做了Mock配置,但运行测试时Mock始终失效,返回Null。相关代码如下:
业务代码中调用的方法
AssignOrderReserveCommandResponseDto response = await _supplyReservesClient.AssignOrderReserve( masterReserveId, inboundReserveId, deliveryDate, orderInfos, cancellationToken)
当前Mock实现
public static readonly ISupplyReservesClient SupplyReservesClient = Substitute.For<ISupplyReservesClient>(); public static AssignOrderReserveCommandResponseDto assignOrderReserveCommandResponse; static SupplyReservesClientMock() { SupplyReservesClient .AssignOrderReserve(Arg.Any<Guid>(), Arg.Any<Guid>(), Arg.Any<DateTimeOffset>(), Arg.Any<IReadOnlyCollection<AssignOrderInfo>>(), Arg.Any<CancellationToken>()) .Returns(_ => assignOrderReserveCommandResponse); } public static void SetAssignOrderReserveCommandResponseDto(long bidId, long otherBidId) { Fixture fixture = new Fixture(); assignOrderReserveCommandResponse = fixture.Build<AssignOrderReserveCommandResponseDto>() .With(x => x.OrderInfos, new List<AssignOrderReserveCommandResponseDto.OrderInfo>() { new(bidId, "1", DateTime.UtcNow.AddDays(3)), new(otherBidId, "1", DateTime.UtcNow.AddDays(3)) }) .With(x => x.InboundReserveId, fixture.Create<Guid>()) .Create(); }
待Mock的目标方法内部逻辑
public async Task<AssignOrderReserveCommandResponseDto> AssignOrderReserve( Guid? masterReserveId, Guid? inboundReserveId, DateTimeOffset deliveryDate, IReadOnlyCollection<AssignOrderInfo> orderInfos, CancellationToken cancellationToken) { AssignOrderReserveCommand command = AssignOrderReserveConverter .Convert(masterReserveId, inboundReserveId, deliveryDate, orderInfos); AssignOrderReserveCommandResponse response = await _supplyReservesClient .AssignOrderReserveAsync(command, cancellationToken: cancellationToken); return AssignOrderReserveConverter.Convert(response); }
核心失效原因
1. Mock的方法与实际执行的方法不匹配
从目标方法的内部逻辑能明确看到:上层代码调用的AssignOrderReserve方法,内部实际转调了AssignOrderReserveAsync方法,而非直接调用外部服务的AssignOrderReserve。但你的Mock仅针对AssignOrderReserve做了配置,完全没处理AssignOrderReserveAsync,导致这个未被Mock的方法返回默认值Null,最终整个流程返回Null。
2. 参数类型匹配错误(次要但需修正)
目标方法中masterReserveId和inboundReserveId的类型是Guid?(可空Guid),但Mock配置中用的是Arg.Any<Guid>()(非空Guid)。如果业务代码中传入的是null值,参数匹配条件会不满足,同样会导致Mock失效返回Null。
修正后的Mock实现示例
public static readonly ISupplyReservesClient SupplyReservesClient = Substitute.For<ISupplyReservesClient>(); public static AssignOrderReserveCommandResponse assignOrderReserveCommandResponse; // 类型改为CommandResponse static SupplyReservesClientMock() { // 修正1:Mock实际调用的AssignOrderReserveAsync方法 SupplyReservesClient .AssignOrderReserveAsync(Arg.Any<AssignOrderReserveCommand>(), Arg.Any<CancellationToken>()) .Returns(_ => assignOrderReserveCommandResponse); // 可选:保留原AssignOrderReserve的Mock,修正参数类型为可空Guid SupplyReservesClient .AssignOrderReserve(Arg.Any<Guid?>(), Arg.Any<Guid?>(), Arg.Any<DateTimeOffset>(), Arg.Any<IReadOnlyCollection<AssignOrderInfo>>(), Arg.Any<CancellationToken>()) .Returns(async (Guid? m, Guid? i, DateTimeOffset d, IReadOnlyCollection<AssignOrderInfo> o, CancellationToken ct) => { var command = AssignOrderReserveConverter.Convert(m, i, d, o); var resp = await SupplyReservesClient.AssignOrderReserveAsync(command, ct); return AssignOrderReserveConverter.Convert(resp); }); } public static void SetAssignOrderReserveCommandResponse(long bidId, long otherBidId) { Fixture fixture = new Fixture(); // 修正:构造AssignOrderReserveCommandResponse实例(而非Dto) assignOrderReserveCommandResponse = fixture.Build<AssignOrderReserveCommandResponse>() .With(x => x.OrderInfos, new List<AssignOrderReserveCommandResponse.OrderInfo>() { new(bidId, "1", DateTime.UtcNow.AddDays(3)), new(otherBidId, "1", DateTime.UtcNow.AddDays(3)) }) .With(x => x.InboundReserveId, fixture.Create<Guid>()) .Create(); }
内容的提问来源于stack exchange,提问作者Tanya
相关产品推荐
相关产品推荐

