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

如何使用Moq在单元测试中设置Exception的InnerException

解决Moq无法设置Exception.InnerException的问题

问题原因

你猜的没错,Exception.InnerException不是virtual属性,Moq仅支持对可重写(virtual/abstract)的成员进行Setup操作,因此直接Mock Exception并设置InnerException会抛出NotSupportedException。

解决方案

方案1:直接实例化Exception(推荐)

无需Mock Exception,直接通过Exception的构造函数传入InnerException即可,这是最简洁直接的方式:

var innerException = new Exception("内部异常信息");
var targetException = new Exception("外层异常信息", innerException);

// 此时targetException.InnerException即为传入的innerException

方案2:自定义可重写InnerException的Exception子类

如果业务场景确实需要Mock Exception类型,可以自定义一个子类,将InnerException设为可重写:

public class MockableException : Exception
{
    public override Exception InnerException { get; }

    public MockableException(Exception innerException)
    {
        InnerException = innerException;
    }
}

// 对自定义子类进行Mock
var innerEx = new Exception();
var exceptionMock = new Mock<MockableException>(innerEx);
// 支持后续Setup操作(因InnerException已变为可重写)
exceptionMock.Setup(e => e.InnerException).Returns(new Exception("新的内部异常"));

方案3:结合反射设置(不推荐)

若必须Mock原生Exception,可开启CallBase让Moq调用基类实现,再通过反射修改InnerException(该方式不够优雅,仅作为特殊场景下的备选):

var exceptionMock = new Mock<Exception> { CallBase = true };
var innerEx = new Exception();

// 通过反射设置私有字段_innerException
typeof(Exception)
    .GetField("_innerException", BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(exceptionMock.Object, innerEx);

// 此时exceptionMock.Object.InnerException即为innerEx

内容的提问来源于stack exchange,提问作者Nashmár

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:25:38