代码之家  ›  专栏  ›  技术社区  ›  Josh Kodroff

我如何验证一个方法被moq调用了一次?

  •  97
  • Josh Kodroff  · 技术社区  · 15 年前

    我如何验证一个方法被moq调用了一次?这个 Verify() VS Verifable() 事情真的很混乱。

    3 回复  |  直到 8 年前
        1
  •  144
  •   Malice    11 年前

    你可以使用 Times.Once() Times.Exactly(1) :

    mockContext.Verify(x => x.SaveChanges(), Times.Once());
    mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1));
    

    以下是关于 Times 班级:

    • AtLeast -指定模拟方法的调用次数应至少为次。
    • AtLeastOnce -指定至少应调用一次模拟方法。
    • AtMost -指定模拟方法的调用次数应为最大时间。
    • AtMostOnce -指定模拟方法最多应调用一次。
    • Between -指定应在从到时间之间调用模拟方法。
    • Exactly -指定模拟方法应精确调用次。
    • Never -指定不应调用模拟方法。
    • Once -指定模拟方法应仅调用一次。

    请记住,它们是方法调用;我总是被绊倒,以为它们是属性,忘记了括号。

        2
  •  6
  •   CodingYoshi    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);
        }
    }
    

    下面是实际的测试,在代码中添加注释,以便进一步澄清:

    [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);
        }
    }
    
        3
  •  2
  •   sanjeev bhusal    9 年前

    测试控制器可以是:

      public HttpResponseMessage DeleteCars(HttpRequestMessage request, int id)
        {
            Car item = _service.Get(id);
            if (item == null)
            {
                return request.CreateResponse(HttpStatusCode.NotFound);
            }
    
            _service.Remove(id);
            return request.CreateResponse(HttpStatusCode.OK);
        }
    

    当使用有效的ID调用DeleteCars方法时,我们可以验证服务移除方法是否通过此测试准确调用了一次:

     [TestMethod]
        public void Delete_WhenInvokedWithValidId_ShouldBeCalledRevomeOnce()
        {
            //arange
            const int carid = 10;
            var car = new Car() { Id = carid, Year = 2001, Model = "TTT", Make = "CAR 1", Price=2000 };
            mockCarService.Setup(x => x.Get(It.IsAny<int>())).Returns(car);
    
            var httpRequestMessage = new HttpRequestMessage();
            httpRequestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration();
    
            //act
            var result = carController.DeleteCar(httpRequestMessage, vechileId);
    
            //assert
            mockCarService.Verify(x => x.Remove(carid), Times.Exactly(1));
        }