Как проверить, что метод был вызван ровно один раз с Moq?
Как проверить, что метод был вызван ровно один раз с Moq? Элемент Verify()
и Verifable()
вещь действительно сбивает с толку.
3 ответа:
можно использовать
Times.Once()
илиTimes.Exactly(1)
:mockContext.Verify(x => x.SaveChanges(), Times.Once()); mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1));
вот методы на времени класс:
AtLeast
- указывает, что издевались метод должен быть вызван раз как минимум.AtLeastOnce
- указывает, что издевались метод должен быть вызван один раз, как минимум.AtMost
- указывает, что издевались метод должен быть вызван каждый раз, как максимум.AtMostOnce
- указывает, что a издевались метод должен быть вызван один раз, как максимум.Between
- указывает, что издевались метод должен быть вызван от и раза.Exactly
- указывает, что издевались метод должен быть вызван ровно раз.Never
- указывает, что издевались метод должен быть вызван.Once
- указывает, что издевались метод должен быть вызван ровно один раз.просто помните, что они вызовы метода; я продолжал спотыкаться, думая, что они были свойствами и забывая скобки.
представьте, что мы строим калькулятор с одним методом для добавления 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); } }
контроллер тестирования может быть:
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); }
и когда метод DeleteCars вызывается с допустимым идентификатором, то мы можем проверить, что метод Service remove вызывается ровно один раз этим тестом :
[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)); }