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

为什么调用someMockInstance.Object会触发类构造函数?如何避免该问题?

问题解答

为什么访问 Mock<T>.Object 会触发原类构造函数

Moq 框架的核心实现原理是动态生成继承自被Mock类型T的代理类,当你首次访问Object属性时,Moq会完成代理类的实例化。
根据C#/.NET的类型系统规则,任何子类实例化时都会自动执行父类的构造函数链,哪怕这个子类是运行时动态生成的代理类也不例外。所以你访问mockFoo.Object时,代理类的实例化会触发父类Foo的构造函数执行。

避免触发构造函数的可行方案

  • 优先基于接口做Mock(最推荐)
    为业务类抽象对应的接口,比如你可以为Foo定义IFoo接口,将需要Mock的方法声明在接口中:
    public interface IFoo
    {
        string DoSomething();
    }
    
    public class Foo : IFoo
    {
        public Foo()
        {
            // Init some stuff
        }
        
        public virtual string DoSomething()
        {
            // Blah
        }
    }
    
    测试时直接Mock接口即可:var mockFoo = new Mock<IFoo>();,接口不存在构造函数,自然不会触发任何构造逻辑,这也是单元测试的公认最佳实践。
  • 拆分构造函数的重逻辑
    如果你确实无法抽取接口,必须Mock具体类,可以把构造函数中不需要在测试中执行的重逻辑拆分到独立的Init类方法中,业务代码中实例化后显式调用初始化方法,这样即使测试时构造函数被调用,也不会执行你想要规避的逻辑。

注意:只要你选择Mock具体类,就无法完全跳过原类构造函数的执行,这是.NET继承机制的固有规则限制,所有继承自该类的实例(包括动态代理实例)都必须执行父类构造逻辑。


内容的提问来源于stack exchange,提问作者Lee Tickett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:36:04