Pregunta

Entonces tengo la siguiente clase:

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

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

Y luego tengo la siguiente prueba:

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

Y la verificación está fallando. Lo he comprobado y el código está llamando al método real B () en lugar de a un método simulado B ().

Tengo un montón de código en ejecución donde Moq funciona perfectamente, y he estado codificando lo suficiente como para darme cuenta de que debo estar haciendo algo mal aquí, pero por mi vida no puedo verlo. He estado asumiendo que desde que llamo test. Object .A (), las llamadas a B () no pasan por el Mock, pero eso realmente no hace ningún para mí, ya que una llamada desde cualquier otro objeto funcionaría igual ...

Entonces, ¿por qué no se ejecuta la configuración burlada?

Editar: Sí, tengo las partes internas visibles para el proyecto de prueba. Tenía la intención de poner eso en la publicación original, ya que sabía que alguien lo mencionaría.

En cuanto al código real, desafortunadamente es MUY patentado, por lo que no puedo publicarlo. Veré si puedo ajustar el código mañana para que realmente se compile.

¿Fue útil?

Solución

No estoy seguro de si la respuesta de Gamlor funciona. Parece que si desea realizar una configuración en un método en el que desea verificar que Class1.MethodA llama a Class1.MethodB, MethodB (que es en el que haría la configuración) debe ser público (independientemente de InternalsVisibleTo). Escribí una prueba simple en una situación similar y descubrí que una vez que hice público mi MethodB, Moq comenzó a trabajar. Apuesto a que si hicieras público tu método B, funcionaría.

Supongo que esto es un error de Castle o Moq, pero no lo sé con seguridad. Esperemos que alguien pueda hacer el timbre.

Sé que hacer público a MethodB no es una buena opción. Pero eso es lo que sé de la situación ...

Otros consejos

El objeto que su simulacro tiene que cumplir con estos criterios para hacer un simulacro exitoso de un método:

  • Tiene que ser una interfaz
  • O el método del que quiere burlarse debe ser un método virtual y público.

Ahora también puedes burlarte del método virtual-interno, pero para permitir que tengas que dar acceso a tus internos a Moq. Esto se puede hacer con:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Esto hace que el interno sea accesible para el generador de código de Moq.

Entonces, para burlarse de su llamada a MyClass.A debe hacer esto:

  1. Haz tu método A virtual.
  2. Y haga público su método o permita el acceso con

    <*>

O como se dijo, cree una interfaz que represente la API de MyClass.

Moq no ajusta el código existente, sino que crea un simulacro vacío.

Eso significa que llamar a testObject.Object.A () no ejecuta su código original, por lo que B nunca se llama.

Si pretendes burlarte de una interfaz, entonces esto tiene sentido porque las interfaces no tienen código, por lo que tampoco lo haría el simulacro.

Intenta crear el simulacro de esta manera (no lo intenté, así que no sé si funciona):

var testObject= new Mock<MyClass> { CallBase = true };
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top