使用Moq模拟被Lazy包裹的接口时触发运行时异常如何解决
问题解决:Moq无法模拟Lazy的Value属性
错误原因
Lazy<T>的Value属性为非可重写成员,Moq框架仅支持对接口成员、抽象类成员、类中标记为virtual的成员做Setup/Verify操作,非可重写成员不支持模拟,所以你尝试对Lazy<IFoo>.Value设置返回值时会抛出对应异常。
解决方案
不需要为Lazy<IFoo>创建Mock对象,直接构造真实的Lazy<IFoo>实例即可。Lazy<T>是.NET运行时提供的可靠基础类型,无需模拟,直接将你已Mock好的IFoo对象传入构造逻辑即可满足测试需求。
你给出的代码同时存在两处笔误需要修正:
MyFooService的构造函数参数当前声明为IFoo类型,注入Lazy<IFoo>类型的参数会触发编译错误,需要将构造参数类型改为Lazy<IFoo>- 实例化服务时的类名拼写错误,
MyService应改为MyFooService
修改后的可运行测试代码如下:
[TestClass] public class MyFooServiceTests { private Mock<IFoo> _fooMock = new Mock<IFoo>(); private MyFooService _service; [TestMethod] public void FooMethod_HappyPath_ShouldReturn() { //Arrange _fooMock .Setup(x => x.DoSomething()) .Returns(1); // 直接构造真实的Lazy实例,无需Mock Lazy<IFoo> lazyFoo = new Lazy<IFoo>(() => _fooMock.Object); _service = new MyFooService(lazyFoo); // 此处补充你的Act、Assert逻辑 } } public interface IFoo { int DoSomething(); } public class MyFooService { // 修正构造参数为Lazy<IFoo>类型 public MyFooService(Lazy<IFoo> foo) { // 业务逻辑实现 } }
内容的提问来源于stack exchange,提问作者Shahar Shokrani
相关产品推荐
相关产品推荐

