Para burlarse de un objeto, ¿tiene que implementar una interfaz o marcarse virtual?

o puede la clase implementar una clase abstracta también?

Para simular un tipo, debe ser una interfaz (esto también se llama ser puramente virtual ) o tener miembros virtuales (los miembros abstractos también son virtuales).

Según esta definición, puede burlarse de todo lo que es virtual .

Esencialmente, los simulacros dynamics no hacen nada que no puedas hacer a mano .

Digamos que estás progtwigndo contra una interfaz como esta:

public interface IMyInterface { string Foo(string s); } 

Puede crear manualmente una implementación específica de prueba de IMyInterface que ignore el parámetro de entrada y siempre devuelva el mismo resultado:

 public class MyClass : IMyInterface { public string Foo(string s) { return "Bar"; } } 

Sin embargo, eso se vuelve muy rápido de manera repetitiva si desea probar cómo el consumidor responde a los diferentes valores de devolución, por lo que en lugar de codificar sus Dobles de prueba a mano, puede tener un marco de trabajo creado dinámicamente por usted.

Imagine que los simulacros dynamics realmente escriben código similar a la implementación de MyClass anterior (en realidad no escriben el código, emiten dinámicamente los tipos, pero es una analogía lo suficientemente precisa).

A continuación, le mostramos cómo definir el mismo comportamiento que MyClass con Moq:

 var mock = new Mock(); mock.Setup(x => x.Foo(It.IsAny())).Returns("Bar"); 

En ambos casos, se llamará al constructor de la clase creada cuando se crea el objeto. Como una interfaz no tiene constructor, este será normalmente el constructor predeterminado (de MyClass y la clase emitida dinámicamente, respectivamente).

Puede hacer lo mismo con tipos concretos como este:

 public class MyBase { public virtual string Ploeh() { return "Fnaah"; } } 

A mano, usted podría derivar de MyBase y anular el método Ploeh porque es virtual:

 public class TestSpecificChild : MyBase { public override string Ploeh() { return "Ndøh"; } } 

Una biblioteca simulada dinámica puede hacer lo mismo, y lo mismo es cierto para los métodos abstractos.

Sin embargo, no puede escribir código que anule un miembro no virtual o interno, y tampoco se puede simular en modo dynamic. Solo pueden hacer lo que puedes hacer a mano.

Advertencia: la descripción anterior es cierta para la mayoría de los simulacros dynamics con la excepción de TypeMock, que es diferente y … aterrador.

Del blog de Stephen Walther :

Puede usar Moq para crear simulaciones desde ambas interfaces y clases existentes. Hay algunos requisitos en las clases. La clase no puede ser sellada. Además, el método que se burla debe marcarse como virtual. No puede simular métodos estáticos (utilice el patrón del adaptador para simular un método estático).