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

如何Mock抛出含入参异常消息的异步方法?

问题

在Mock包含Task<List<int>> GetIdsAsync(int)方法的ISomething接口时,已实现通过入参生成返回值:

mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
    .ReturnsAsync((int n) => new List<int>(n));

也能Mock该方法抛出固定异常:

mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
    .ThrowsAsync(new InvalidOperationException());

但希望抛出包含入参的异常:throw new InvalidOperationException($"{n} is not valid");,即使用入参生成异常消息。尝试了以下写法:

mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
    .ThrowsAsync((int n) => new InvalidOperationException($"{n} is not valid"));

但出现报错:

CS1929 'ISetup<ISomething, Task<List<int>>>' does not contain a
definition for 'ThrowsAsync' and the best extension method overload
'SequenceExtensions.ThrowsAsync(ISetupSequentialResult<Task>,
Exception)' requires a receiver of type 'ISetupSequentialResult<Task>'

请问正确的语法应该是什么?

解决方案

有两种正确写法可以实现需求:

方法一:利用ReturnsAsync手动抛出异常

异步方法的ReturnsAsync支持传入带参数的委托,可在委托内直接抛出目标异常:

mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
    .ReturnsAsync((int n) => 
    {
        throw new InvalidOperationException($"{n} is not valid");
    });

方法二:使用Throws结合参数委托

对于异步方法,Moq的Throws方法支持接受带参数的委托,会自动处理异步场景下的异常抛出逻辑:

mock.Setup(x => x.GetIdsAsync(It.IsAny<int>()))
    .Throws((int n) => new InvalidOperationException($"{n} is not valid"));

报错原因:ThrowsAsync的重载仅支持直接传入异常实例,或用于顺序Mock场景,不支持通过带参数的委托动态生成异常。上述两种写法利用了支持参数委托的ReturnsAsync或Throws方法,实现了根据入参生成异常消息的需求。

内容的提问来源于stack exchange,提问作者Mr. Boy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:55:29