Verificar una llamada al método usando Moq

142

Soy bastante nuevo en las pruebas unitarias en C # y estoy aprendiendo a usar Moq. A continuación se muestra la clase que estoy tratando de probar.

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...
    }
}

A continuación se muestra mi 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>()));
    }
}

Me sale la siguiente excepción:

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

Solo quiero verificar si se llama o no al método "MyMethod". ¿Me estoy perdiendo de algo?

usuario591410
fuente
1
Eso no se compilará si SomeClassno tiene una definición para MyMethod(string), lo que parece que no tiene.
Platinum Azure
lo siento ... edité mi pregunta ..
user591410
1
Estás en el camino correcto, pero hay errores en el código publicado. No se compilará: carcasa en Someclass, anulación de retorno en DoSomething. Después de eso, necesita acceso público, luego haga DoSomething virtual. En resumen, probablemente tenga un error en su código de producción también.
TrueWill
Gracias por su respuesta. Estaba configurando los argumentos incorrectamente mientras configuraba el método simulado ..
user591410
"No hay configuraciones configuradas". Podría ser engañoso. No necesita configurar un comportamiento para los métodos que se llamarán. Y también recuerde ejecutar el método "Verificar" DESPUÉS de que se llame al método que está probando (por lo que está bien en su caso).
Sielu

Respuestas:

208

Estás comprobando el método incorrecto. Moq requiere que configure (y luego opcionalmente verifique) el método en la clase de dependencia.

Deberías estar haciendo algo más como esto:

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();
    }
}

En otras palabras, está verificando esa llamada MyClass#MyMethod, su clase definitivamente llamará SomeClass#DoSomethinguna vez en ese proceso. Tenga en cuenta que no necesita el Timesargumento; Solo estaba demostrando su valor.

Azul platino
fuente
Lo siento, edité mi pregunta con el método correcto. Como mencionó, primero probé la configuración y luego realicé la verificación. Todavía me da la misma excepción.
user591410
22
¿No es redundante configurar una expectativa y luego verificar explícitamente la misma expectativa? ¿No mockSomeClass.VerifyAll();lograría el mismo resultado y estaría más SECO?
Tim Long
14
Sí, pero algunas personas prefieren ser explícitas.
Platinum Azure
3
Gracias por al menos mencionar VerifyAll (); aunque obvio una vez que lo piensas. Podría haber optado por el enfoque explícito, pero mucho más limpio al usar el todo. Agradecido ambos están en la lista.
JGood
1
Una desventaja relacionada en Mockcomparación con NSubstitutees que si está tratando de verificar también los parámetros y la verificación falla, solo muestra qué invocaciones se realizaron, pero no muestra qué se esperaba exactamente si usó variables en la expresión de verificación: solo mostrará la variable nombre, no su valor, por lo que deberá depurar para verificar qué valor tiene exactamente esa variable. NSubstitute solo mostrará valores de ambos e incluso donde era diferente.
Grengas