CallBase = true In Moq

7

团队大家好,我是moq新手,不太理解的概念是:

CallBase = true;
var mock = new Mock<IFoo> { CallBase = true };

根据Git Hub的说法:如果没有覆盖成员的期望值,则调用基类实现。但是,我有下面的测试用例,在没有使用CallBase = true的情况下就能够模拟基类成员。
// Creating Base class.
public abstract class Car
{  
   public virtual bool IsValidSpeed()
    {
        ///complex logic
        ///returnig false just to compile code
        return false;
    }
}

// Creating child class
public class Ferrari : Car
{
    public int Speed { get; set; }
     public void PrintSpeed(int speed)
    {
        if (IsValidSpeed())
        {
            Speed = speed;
        }
    }
}

以下是编写测试用例。 我没有为我的模拟对象设置CallBase = true属性。

 public void MoqPracticeTest2()
 {
    //  var mock = new Mock<Ferrari>() { CallBase = true }; 
    var mock = new Mock<Ferrari>(MockBehavior.Strict);
    //Mocking Base class function
    mock.Setup(x=>x.IsValidSpeed()).Returns(true); 
    //calling function which will call base function
    mock.Object.PrintSpeed(100);
    //calling Verify on mock object
    mock.Verify(x => x.IsValidSpeed(), Times.Once);
    Assert.AreEqual(mock.Object.Speed,100); //Doing Assert
 }

仍然存在一个测试用例,在未设置回调属性的情况下通过了测试。 请问有人能解释一下这里使用 CallBase = true 的作用吗?


@chirstos 我使用了 var mock = new Mock<Ferrari>() { CallBase = true }; //var mock = new Mock<Ferrari>(MockBehavior.Strict); 现在我的测试用例也通过了。我正在使用最新的 moq dll。 - Abhinav Singh
我假设你也有这个语句 mock.Setup(x=>x.IsValidSpeed()).Returns(true);。如果是这样的话,这很合理,因为只有当你没有提供类似上述设置时,才会调用基本实现。 - Christos
1个回答

5

您不需要将CallBase设置为true,因为您只想验证在IsValidSpeed()返回true的情况下,Ferrari对象的速度将是提供给PrintSpeed方法的速度。

因此,通过声明以下内容:

mock.Setup(x=>x.IsValidSpeed()).Returns(true);

您可以模拟这种特定的场景,不需要详细了解 IsValidSpeed 的实现细节。
另一方面,请尝试删除上面的行并将 CallBase 设置为 true。这时您应该会注意到断言会失败。这是因为实际方法会被调用,并返回值为 false,正如您在帖子中已经提到的那样。因此在这种情况下,所提供的速度值将不会被分配给 Speed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接