IMediator Mock returns null 当我在测试中设置它时

IMediator Mock returns null when I set up it in test

这是我的代码:

public sealed class BulkAddStockConditionItemCommandHandler : IRequestHandler<BulkAddStockConditionItemCommand,
    UserStockConditionSetsEntity>
{

    private readonly IMediator _mediator;


    public BulkAddStockConditionItemCommandHandler(IMediator mediator)
    {

        _mediator = mediator;
  
    }

    public async Task<UserStockConditionSetsEntity> Handle(BulkAddStockConditionItemCommand request,
        CancellationToken cancellationToken)
    {
        var conditionalRiskAgreements = new ConditionalRiskAgreementEntity(_userService.CustomerIsin);

        var addRes = await _mediator.Send(new AcceptConditionalRiskAgreementCommand(), cancellationToken);

        if (addRes == null) throw new Exception();


        //...code removed for brevity
    }
}

我将 IMediator 注入到我的构造函数中,我需要 addRes 不是 NULL 在我的单元测试场景中,所以在这里你可以看到我的测试场景:

public async void BulkAddStockConditionItemCommand_when_StockConditionSet_is_null()
{
    //arrange
    
    var condition = new ConditionalRiskAgreementEntity(RandomIsin);

    var mediator = new Mock<IMediator>();

    mediator.Setup(i => i.Send(It.IsAny<ConditionalRiskAgreementEntity>(), It.IsAny<System.Threading.CancellationToken>())).ReturnsAsync(Task.FromResult<object>(condition));

    BulkAddStockConditionItemCommand command = new BulkAddStockConditionItemCommand(data);
    BulkAddStockConditionItemCommandHandler handler = new BulkAddStockConditionItemCommandHandler(mediator.Object, userservice.Object, repoacc.Object, CacheableRepository.Object);

    //Act

    var caughtException = await Assert.ThrowsAsync<Exception>(() => handler.Handle(command, new System.Threading.CancellationToken()));

    //Assert
    Assert.IsType<Exception>(caughtException);

}

我将 IMediator 设置为但是当我 运行 测试它时 returns null 而不是 condition 变量。为什么?

根据显示的代码,被测对象使用AcceptConditionalRiskAgreementCommand

//...

var addRes = await _mediator.Send(new AcceptConditionalRiskAgreementCommand(), cancellationToken);

//...

但在测试中,模拟调解器设置为预期 ConditionalRiskAgreementEntity

//...

mediator.Setup(i => i.Send(It.IsAny<ConditionalRiskAgreementEntity>(), It.IsAny<System.Threading.CancellationToken>()))
    .ReturnsAsync(Task.FromResult<object>(condition));

//...

当参数匹配器在调用的成员中不匹配时,模拟将 return null 默认情况下。

没有必要在 ReturnsAsync 中 return Task.FromResult<object>(condition) 因为那会把你传入的任何东西都包裹在 Task

首先,我建议您重构测试以使用 async Task 而不是 async void,然后更新模拟以期望被测对象中使用的实际参数类型。

public async Task BulkAddStockConditionItemCommand_when_StockConditionSet_is_null() {
    //Arrange
    var condition = new ConditionalRiskAgreementEntity(RandomIsin);

    var mediator = new Mock<IMediator>();

    mediator
        .Setup(i => i.Send(It.IsAny<AcceptConditionalRiskAgreementCommand>(), It.IsAny<System.Threading.CancellationToken>()))
        .ReturnsAsync(condition);

    BulkAddStockConditionItemCommand command = new BulkAddStockConditionItemCommand(data);
    BulkAddStockConditionItemCommandHandler handler = new BulkAddStockConditionItemCommandHandler(mediator.Object, userservice.Object, repoacc.Object, CacheableRepository.Object);

    //Act
    var caughtException = await Assert.ThrowsAsync<Exception>(() => handler.Handle(command, new System.Threading.CancellationToken()));

    //Assert
    Assert.IsType<Exception>(caughtException);
}