Comment vérifier que cette méthode n'a PAS été appelée dans Moq?


466

Comment vérifier que cette méthode n'a PAS été appelée dans Moq ?

At-il quelque chose comme AssertWasNotCalled?

MISE À JOUR: à partir de la version 3.0, une nouvelle syntaxe peut être utilisée:

mock.Verify(foo => foo.Execute("ping"), Times.Never());

Réponses:


155

MISE À JOUR : Depuis la version 3, vérifiez la mise à jour de la question ci-dessus ou la réponse de Dann ci-dessous.

Soit, rendez votre maquette stricte afin qu'elle échoue si vous appelez une méthode pour laquelle vous n'avez aucune attente

new Mock<IMoq>(MockBehavior.Strict)

Ou, si vous voulez que votre maquette soit lâche, utilisez le .Throws (Exception)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));

9
... ou Callback () pour définir un indicateur qui peut être affirmé.
alex

2
De plus, avec l'option # 2, vous ne pouvez pas avoir un VerifyAll dans une méthode Teardown générale - il échouera en disant que l'attente n'a pas été satisfaite; quand le test devrait idéalement réussir.
Gishu

51
Ce n'est pas vraiment une "vérification non appelée" car elle pourrait être prise dans la méthode et fonctionnerait toujours - fournissant un faux positif!
Dan

4
Expect est désormais obsolète
Tomasz Sikora

5
Cela aurait pu être le meilleur moyen possible en 2009, mais certainement pas maintenant. désolé
Fabio Milheiro

537

Exécutez une vérification après le test qui a un Times.Neverensemble d'énumérations. par exemple

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());

4
Ce qui est essentiel ici, c'est que l'appel Verify (action, Never) est après l'appel à la maquette. Je pensais qu'il mettait en place la vérification pour appeler VerifyAll () plus tard (ce qui ne fonctionne pas )
piers7

Simple et efficace. Merci.
Ian Grainger

45

Volé à: Réponse de John Foster à la question "Besoin d'aide pour mieux comprendre Moq"

L'une des choses que vous voudrez peut-être tester est que la méthode de rémunération n'est pas appelée lorsqu'une personne âgée de plus de 65 ans est transmise à la méthode

[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

Cela ne fonctionne pas dans les versions récentes de Moq (depuis au moins 3.1), cela devrait être spécifié dans la Verifyméthode comme mentionné dans la réponse.

En fait, il est préférable de spécifier .AtMost(0)après l'instruction Returns.

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

Bien que le «jette» fonctionne également, AtMost(0)est plus expressif à mon humble avis.


-5

Utilisez .AtMostOnce ();

Après le vrai test, appelez à nouveau la méthode. S'il lève une exception, il a été appelé.


1
N'est-ce pas un peu trop obscur pour affirmer que l'exception a été levée par un framework moqueur?
alex

Pourquoi? Vérifiez simplement le type de l'exception. Si c'est l'un jeté mon Moq, vous êtes en sécurité.
Aaron Digulla

8
Utiliser Verify avec Times.Never n'est pas un meilleur choix ... Je suis d'accord avec alex que cette solution fonctionne, mais est certainement obscure.
Bip bip
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.