如何使用Moq验证方法是否只调用一次?

Jos*_*off 104 .net moq mocking

如何使用Moq验证方法是否只调用一次?在Verify()Verifable()东西实在是令人困惑的.

Jef*_*ata 154

您可以使用Times.Once(),或Times.Exactly(1):

mockContext.Verify(x => x.SaveChanges(), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1));
Run Code Online (Sandbox Code Playgroud)

以下是Times类的方法:

  • AtLeast - 指定应该以最少的次数调用模拟方法.
  • AtLeastOnce - 指定应该至少调用一次模拟方法.
  • AtMost - 指定应将timeed作为最大值调用模拟方法.
  • AtMostOnce - 指定应该最多调用一次模拟方法.
  • Between - 指定应在from和to之间调用模拟方法.
  • Exactly - 指定应该多次调用模拟方法.
  • Never - 指定不应调用模拟方法.
  • Once - 指定应该只调用一次模拟方法.

记住它们是方法调用; 我不断被绊倒,认为他们是属性而忘记了括号.

  • 那么如何获取/设置mockContext? (2认同)
  • @Choco我认为这只是他的Mock实例.所以它就像`var mockContext = new Mock <IContext>()`来设置它. (2认同)

Cod*_*shi 8

想象一下,我们正在构建一个计算器,其中有一种方法可以添加2个整数.让我们进一步想象一下,当调用add方法时,它会调用print方法一次.以下是我们如何测试这个:

public interface IPrinter
{
    void Print(int answer);
}

public class ConsolePrinter : IPrinter
{
    public void Print(int answer)
    {
        Console.WriteLine("The answer is {0}.", answer);
    }
}

public class Calculator
{
    private IPrinter printer;
    public Calculator(IPrinter printer)
    {
        this.printer = printer;
    }

    public void Add(int num1, int num2)
    {
        printer.Print(num1 + num2);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是代码中包含注释的实际测试,以便进一步说明:

[TestClass]
public class CalculatorTests
{
    [TestMethod]
    public void WhenAddIsCalled__ItShouldCallPrint()
    {
        /* Arrange */
        var iPrinterMock = new Mock<IPrinter>();

        // Let's mock the method so when it is called, we handle it
        iPrinterMock.Setup(x => x.Print(It.IsAny<int>()));

        // Create the calculator and pass the mocked printer to it
        var calculator = new Calculator(iPrinterMock.Object);

        /* Act */
        calculator.Add(1, 1);

        /* Assert */
        // Let's make sure that the calculator's Add method called printer.Print. Here we are making sure it is called once but this is optional
        iPrinterMock.Verify(x => x.Print(It.IsAny<int>()), Times.Once);

        // Or we can be more specific and ensure that Print was called with the correct parameter.
        iPrinterMock.Verify(x => x.Print(3), Times.Once);
    }
}
Run Code Online (Sandbox Code Playgroud)