Domanda

Quindi ho la seguente classe:

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

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

E poi ho il seguente test:

...
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));

E la verifica non riesce. Ho controllato e il codice chiama il metodo reale B () anziché un metodo B () deriso.

Ho un sacco di codice in esecuzione in cui Moq funziona perfettamente, e ho programmato abbastanza a lungo per capire che qui devo fare qualcosa di sbagliato, ma per la mia vita non riesco a vederlo. Ho proceduto partendo dal presupposto che da quando chiamo test. Oggetto .A (), le chiamate a B () non stanno attraversando il Mock, ma in realtà non ne fanno ha senso per me dal momento che una chiamata da qualsiasi altro oggetto avrebbe funzionato allo stesso modo ...

Quindi, perché mai la configurazione derisa non viene eseguita?

Modifica: Sì, ho gli interni visibili al progetto di test. Volevo metterlo nel post originale, poiché sapevo che qualcuno lo avrebbe menzionato.

Per quanto riguarda il codice reale, purtroppo è MOLTO proprietario, quindi non posso pubblicarlo. Vedrò se posso modificare il codice domani per renderlo effettivamente compilare.

È stato utile?

Soluzione

Non sono sicuro che la risposta di Gamlor funzioni. Sembra che se si desidera eseguire un'installazione su un metodo in cui si desidera verificare che Class1.MethodA chiami Class1.MethodB, MethodB (che è quello su cui si farebbe l'installazione) deve essere pubblico (indipendentemente da InternalsVisibleTo). Ho scritto un semplice test in una situazione simile e ho scoperto che una volta reso pubblico il mio MethodB, Moq ha iniziato a funzionare. Scommetto che se rendessi pubblico il tuo metodo B, funzionerebbe.

Presumo che si tratti di un bug Castle o Moq ma non lo so per certo. Eventualmente qualcuno entrerà.

So che rendere MethodB pubblico non è una buona scelta. Ma questo è quello che so della situazione ...

Altri suggerimenti

L'oggetto che il tuo Mock deve soddisfare questi criteri per rendere un metodo di derisione con successo:

  • Deve essere un'interfaccia
  • O il metodo che vuoi deridere deve essere un metodo virtuale e pubblico.

Ora puoi anche deridere il metodo interno-virtuale, ma per consentire che tu debba dare a Moq l'accesso ai tuoi interni. Questo puoi farlo con:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Ciò rende l'interno accessibile al generatore di codice di Moq.

Quindi, per deridere il tuo MyClass.A devi fare questo:

  1. Rendi il tuo metodo A virtuale.
  2. E rendi pubblico il tuo metodo o consenti l'accesso con

    <*>

O come detto, crea un'interfaccia che rappresenti l'API di MyClass.

Moq non racchiude il codice esistente, ma crea invece una simulazione vuota.

Ciò significa che chiamare testObject.Object.A () non esegue il codice originale, quindi B non viene mai chiamato.

Se fai finta di deridere un'interfaccia, questo ha senso perché le interfacce non hanno codice, quindi nemmeno la derisione.

Prova a creare il mock in questo modo (non l'ho provato, quindi non so se funziona):

var testObject= new Mock<MyClass> { CallBase = true };
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top