如何使用Moq调用类中的另一个方法

Ada*_*dam 15 moq

这似乎很简单,但我似乎无法让它工作.

我有一个带有Save方法的类,它只调用另一个方法ShouldBeCalled().我想验证,如果我调用Save(),其他方法ShouldBeCalled()至少执行一次.我以为我可以做到以下几点.

public class ClassA
{
    public virtual void Save()
    {
        ShouldBeCalled();
    }

    public virtual void ShouldBeCalled()
    {
        //This should get executed
    }
}

[TestFixture]
public class ClassA_Test
{
    [Test]
    public void Save_Should_Call_ShouldBeCalled()
    {
        var mockClassA = new Mock<ClassA>();
        mockClassA.Object.Save();

        mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到异常"模拟的预期调用至少一次,但从未执行过:x => x.ShouldBeCalled()"

这只是一个猜测,但是Moq用它自己的版本重写了Save()方法,它忽略了我在真实对象的Save()方法中的任何东西.

And*_*mes 29

您遇到此问题是因为您在嘲笑您正在测试的内容.这没有意义.

你是正确的,Moq将用自己的方法替换你的方法的实现.原因是你应该使用Moq模拟你正在测试的类,而不是你正在测试的类.

如果你的代码是这样设计的,那么这个测试是合适的:

public class ClassA
{
    BusinessLogicClass bl;
    public ClassA(BusinessLogicClass bl)
    {
         this.bl = bl;
    }

    public void Save()
    {
        bl.ShouldBeCalled();
    }
}

public class BusinessLogicClass
{
    public virtual void ShouldBeCalled()
    {
        //This should get executed
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这是对该方法的正确测试:

[TestFixture]
public class ClassA_Test
{
    [Test]
    public void Save_ShouldCallShouldBeCalled()
    {
        //Arrange
        var mockBLClass = new Mock<BusinessLogicClass>();
        mockBLClass.Setup(x => x.ShouldBeCalled()).Verifyable();

        //Act    
        ClassA classA = new ClassA(mockBLClass.Object);
        classA.Save();

        //Assert
        mockBLClass.VerifyAll();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的关键教训是,您可以模拟/存储测试需要运行的内容,而不是您自己测试的内容.

希望这有帮助,安德森


Eri*_*lfs 5

尝试使用 CallBase = true 和 false。我运行了你的代码,它有效。

var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true;
mockClassA.Object.Save();
mockClassA.CallBase = false;
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
Run Code Online (Sandbox Code Playgroud)