Как проверить, что метод не был вызван в Moq?

466

Как я могу убедиться, что этот метод НЕ был вызван в Moq ?

Есть ли что-то вроде AssertWasNotCalled?

ОБНОВЛЕНИЕ: Начиная с версии 3.0, можно использовать новый синтаксис:

mock.Verify(foo => foo.Execute("ping"), Times.Never());
Алекс
источник

Ответы:

155

ОБНОВЛЕНИЕ : начиная с версии 3, проверьте обновление на вопрос выше или ответ Данна ниже.

Либо сделайте свой макет строгим, чтобы он потерпел неудачу, если вы вызовете метод, для которого вы не ожидаете

new Mock<IMoq>(MockBehavior.Strict)

Или, если вы хотите, чтобы ваш макет был свободным, используйте .Throws (Исключение)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Дэн Фиш
источник
9
... или Callback (), чтобы установить какой-либо флаг, который может быть утвержден.
Алекс
2
Также с опцией №2 вы не можете иметь VerifyAll в общем методе Teardown - он потерпит неудачу, говоря, что ожидание не было выполнено; когда тест в идеале должен пройти.
Гишу
51
На самом деле это не «проверка не вызвана», поскольку она может быть обнаружена в методе и все равно будет работать - обеспечивая ложное срабатывание!
Дан
4
Ожидание теперь устарело
Томаш Сикора
5
Это могло бы быть наилучшим способом в 2009 году, но, конечно, не сейчас. извините
Фабио Мильейру
537

Запустите проверку после теста, для которого Times.Neverзадано перечисление. например

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Дэн
источник
4
Здесь важно то, что вызов Verify (action, Never) выполняется после вызова макета. Я думал, что это настраивает проверку для вызова VerifyAll () позже (который не работает)
piers7
Просто и эффективно. Спасибо.
Ян Грейнджер
45

Украдено у: ответ Джона Фостера на вопрос: «Нужна помощь, чтобы лучше понять Мок»

Одной из вещей, которую вы можете захотеть проверить, является то, что метод оплаты не вызывается, когда в метод передается человек старше 65 лет.

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}
Крис Марисик
источник
10

Это не работает в последних версиях Moq (начиная с версии 3.1), это должно быть указано в Verifyметоде, как указано в ответе.

На самом деле, это лучше указывать .AtMost(0)после оператора Returns.

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);

Хотя «броски» тоже работают, AtMost(0)более выразительно ИМХО.

Miha
источник
-5

Используйте .AtMostOnce ();

После реального теста, вызовите метод снова. Если он выдает исключение, он вызывается.

Аарон Дигулла
источник
1
Не слишком ли мало, чтобы утверждать, что исключение было выброшено насмешливой структурой?
Алекс
Почему? Просто проверьте тип исключения. Если это один бросил мой Moq, вы в безопасности.
Аарон Дигулла
8
Использование Verify with Times.Никогда не лучший выбор ... Я согласен с alex, что это решение работает, но определенно неясно.
Звуковой сигнал