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.