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

Moq 4.2中抽象类Mock实例转为接口后属性返回默认值如何解决

问题原因

这个行为是Moq的默认实现逻辑导致的:

  • 你以抽象类类型访问Thingy时,因为该成员没有标记为virtual,Moq不会重写它,所以调用的是抽象类本身的实现,输出正常的Howdy
  • 当你将实例转为IFoo接口访问时,Moq会为该接口生成独立的隐式代理实现,这个实现默认不会和抽象类的Thingy属性做关联,所以直接返回对应类型的默认值(这里string的默认值为null,所以输出为空),单独调用As<IFoo>()却没有配置接口成员的返回值,自然解决不了问题。

可行解决方案

方案1:修改抽象类属性为虚属性(最推荐,改造成本最低)

只要将抽象类中实现的接口属性标记为virtual,Moq就会自动把接口的实现关联到该虚属性,两种访问方式都会走抽象类的原有实现:

public abstract class Foo : IFoo
{
    public Foo() { Thingy = "Howdy"; }
    // 新增virtual修饰符
    public virtual string Thingy { get; }
}

修改后原测试代码不需要做任何改动,两次输出都会是Howdy。

方案2:手动配置接口成员的返回值(适合不能修改原有类代码的场景)

如果无法修改抽象类的定义,可以在创建Mock后手动给IFoo接口的属性配置返回值,绑定到抽象类实例的属性即可:

public void DoIt()
{
    var foo = new Mock<Foo>();
    // 手动配置IFoo的Thingy返回值
    foo.As<IFoo>().Setup(f => f.Thingy).Returns(foo.Object.Thingy);
    Console.WriteLine(foo.Object.Thingy);              // 输出"Howdy"
    Console.WriteLine((foo.Object as IFoo).Thingy);    // 输出"Howdy"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:06:07