Moq 父接口中的方法抛出异常

Moq a method in a parent interface throw Exception

我有如下定义

public interface I1 {
    Task RunAsync();
}

public abstract class A{
    protected I1 iInstance;
    public A(I1 i){ this.iInstance = i; }
}

public interface I2 : I1 {}

public class B : A {
    public B(I2 i2):base(i2){}

    public async Task Method1(){
       await this.iInstance.RunAsync()
    }
}

我正在尝试使用像这样的最小起订量来模拟 B.Method1

 var mockI2 = new Mock<I2>();
 mockI2.Setup(i => i.RunAsync()).Verifyable();

 var binstance = new B(mockI2.Object);
 binstance.Method1();

当它到达行 await this.iInstance.RunAsync() 时,我可以看到 this.iInstance 有一个模拟对象,但是对 RunAsync 的调用会抛出异常并显示消息

"Object reference not set to an instance of an object."

看起来这些方法并没有真正被嘲笑,我担心与层次结构有关。 在我的沮丧中,我尝试使用 CallBase = true,到 mockI2 没有太多意义,但我尝试不改变行为。

你的异步方法现在 returns null 但应该 return 可等待的结果 - Task,尝试像这样配置你的异步方法:

var mockI2 = new Mock<I2>();
 mockI2.Setup(i => i.RunAsync).Returns(Task.CompletedTask);

这里的问题是您没有正确设置界面模拟。请记住,您的 RunAsync() 方法 return 是 Task,因此您需要将 mock 设置为 return 和 Task。这是一种方法:

[TestMethod]
public async Task TestMethod1()
{
    _mockI2.Setup(x => x.RunAsync()).Returns(Task.FromResult(true));

    await _bInstance.Method1();

    _mockI2.Verify(x => x.RunAsync(), Times.Once);           
}

这样做可以将您的模拟设置为 return 完成的任务。然后,当您确认它已被调用时,它应该可以工作。