Question

J'ai donc la classe suivante:

public class MyClass {
  internal void A() {
    foreach(Thing thing in ThingArray)
      B(thing);
  }

  virtual internal void B(Thing thing)
  {
    //  do some stuff
  }
}

Et puis j'ai le test suivant:

...
var testObject = new Mock<MyClass>(parameters);
testObject.Setup(t => t.B(It.IsAny<Thing>()));

test.Object.A();

test.Verify(t => t.B(It.IsAny<Thing>()), Times.Exactly(2));

Et la vérification échoue. J'ai vérifié et le code appelle la vraie méthode B () par opposition à une méthode B () simulée.

J'ai beaucoup de code en cours d'exécution où Moq fonctionne parfaitement, et je code depuis assez longtemps pour me rendre compte que je dois faire quelque chose de mal ici, mais pour ma vie, je ne le vois pas. Je suis parti du principe que, depuis que j'appelle test. Objet .A (), les appels à B () ne passent pas par le simulacre, mais cela ne rend vraiment rien. sens pour moi car un appel de tout autre objet fonctionnerait de la même façon ...

Alors, pourquoi la configuration simulée n’est-elle pas exécutée?

Modifier: Oui, les éléments internes sont visibles pour le projet test. Je voulais mettre cela dans le message original, car je savais que quelqu'un le mentionnerait.

Quant au code réel, il est malheureusement TRES propriétaire, je ne peux donc pas le publier. Je verrai si je peux ajuster le code demain pour le compiler réellement.

Était-ce utile?

La solution

Je ne suis pas sûr que la réponse de Gamlor fonctionne. Il semble que si vous souhaitez effectuer une configuration sur une méthode pour vérifier que Class1.MethodA appelle Class1.MethodB, MethodB (celle sur laquelle vous effectuez la configuration) doit être publique (indépendamment de InternalsVisibleTo). J'ai écrit un test simple dans une situation similaire et j'ai constaté qu'une fois que j'ai rendu ma méthode publique B, Moq a commencé à fonctionner. Je parierais que si vous rendiez votre méthode B publique, cela fonctionnerait.

Je suppose qu'il s'agit d'un bogue Castle ou Moq mais je ne le sais pas avec certitude. J'espère que quelqu'un va intervenir.

Je sais que rendre MethodB public n'est pas un bon choix. Mais c’est ce que je sais de la situation ...

Autres conseils

L'objet que votre maquette doit répondre à ces critères afin de réussir à simuler une méthode:

  • Ce doit être une interface
  • Ou la méthode que vous voulez simuler doit être une méthode virtuelle et publique.

Maintenant, vous pouvez également vous moquer de la méthode virtual-internal, mais pour permettre cela, vous devez donner à Moq l’accès à vos ressources internes. Vous pouvez le faire avec:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Ceci rend l’interne accessible au générateur de code de Moq.

Pour simuler votre appel MyClass.A , vous devez procéder comme suit:

  1. Make you method A virtual.
  2. Et rendre votre méthode publique ou autoriser l'accès avec

    <*>

Ou comme indiqué, créez une interface qui représente l'API de MyClass.

Moq n'enveloppe pas le code existant, mais crée une maquette vide.

Cela signifie que l'appel de testObject.Object.A () n'exécute pas votre code d'origine. B n'est donc jamais appelé.

Si vous prétendez que vous vous moquez d'une interface, alors c'est logique, car les interfaces n'ont pas de code, donc le simulacre ne le serait pas non plus.

Essayez de créer la maquette comme ceci (je ne l'ai pas essayée, donc je ne sais pas si cela fonctionne):

var testObject= new Mock<MyClass> { CallBase = true };
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top