Verifica una chiamata di metodo utilizzando Moq


142

Sono abbastanza nuovo nei test unitari in C # e sto imparando ad usare Moq. Di seguito è la classe che sto cercando di testare.

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

Di seguito è la mia TestClass:

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

Ottengo la seguente eccezione:

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

Voglio solo verificare se il metodo "MyMethod" viene chiamato o meno. Mi sto perdendo qualcosa?


1
Ciò non verrà compilato se SomeClassnon ha una definizione per MyMethod(string)cui sembra che non lo sia.
Platinum Azure

scusa..ho modificato la mia domanda ..
user591410

1
Sei sulla buona strada, ma ci sono bug nel codice pubblicato. Non verrà compilato: involucro su Someclass, annullamento del ritorno su DoSomething. Dopodiché hai bisogno dell'accesso pubblico, quindi rendi DoSomething virtuale. In breve, probabilmente hai anche un bug nel tuo codice di produzione.
TrueWill

Grazie per la risposta. Stavo impostando gli argomenti in modo errato durante l'impostazione del metodo finto ..
user591410

"Nessuna configurazione configurata." Potrebbe essere fuorviante. Non è necessario impostare un comportamento per i metodi che verranno chiamati. E ricorda anche di eseguire il metodo "Verifica" DOPO che il metodo che stai testando dovrebbe essere chiamato (quindi va bene nel tuo caso).
Sielu,

Risposte:


209

Stai verificando il metodo sbagliato. Moq richiede l'installazione (e quindi la verifica facoltativa) del metodo nella classe di dipendenza.

Dovresti fare qualcosa di più simile a questo:

class MyClassTest
{
    [TestMethod]
    public void MyMethodTest()
    {
        string action = "test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

        mockSomeClass.Setup(mock => mock.DoSomething());

        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);

        // Explicitly verify each expectation...
        mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

        // ...or verify everything.
        // mockSomeClass.VerifyAll();
    }
}

In altre parole, stai verificando che chiamando MyClass#MyMethod, la tua classe chiamerà sicuramente SomeClass#DoSomethinguna volta in quel processo. Nota che non hai bisogno Timesdell'argomento; Stavo solo dimostrando il suo valore.


Spiacente, ho modificato la mia domanda con il metodo giusto. Come hai detto, ho provato prima SetUp e poi ho eseguito Verifica. Mi dà ancora la stessa eccezione.
user591410

22
Non è ridondante impostare un'aspettativa, quindi verificare esplicitamente la stessa aspettativa? Non mockSomeClass.VerifyAll();otterresti lo stesso risultato ed essere più ASCIUTTO?
Tim Long

14
Sì, ma alcune persone preferiscono essere esplicite.
Platinum Azure

3
Grazie per aver menzionato almeno VerifyAll (); mentre ovvio una volta che ci pensi. Avrei potuto optare per l'approccio esplicito, ma molto più pulito usando il tutto. Per fortuna entrambi sono elencati.
JGood

1
Uno svantaggio correlato di Mockrispetto a NSubstituteè che se stai cercando di verificare anche i parametri e la verifica fallisce, mostra solo quali invocazioni sono state eseguite, ma non mostra esattamente cosa ci si aspettava se hai usato le variabili nell'espressione di verifica - mostrerà solo la variabile nome, non il suo valore, quindi dovrai eseguire il debug per verificare quale valore ha esattamente quella variabile. NSubstitute mostrerà solo i valori di entrambi e anche dove era diverso.
Grengas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.