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

时间:2017-03-13 23:21:36

标签: c# unit-testing moq

我有以下定义

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()
    }
}

我试图使用这样的moq模拟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的调用会抛出异常并显示消息

  

&#34;对象引用未设置为对象的实例。&#34;

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

2 个答案:

答案 0 :(得分:2)

这里的问题是您没有正确设置界面模拟。请注意,您的RunAsync()方法会返回Task,因此您需要设置模拟以返回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);           
}

执行此操作会设置模拟以返回已完成的任务。然后,当您验证它已被调用时,它应该可以工作。

答案 1 :(得分:0)

您的异步方法现在返回null但是应该返回等待结果 - Task,请尝试像这样配置您的异步方法:

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