c# mocking rhino-mocks

c# - Resultados del método de burla



mocking rhino-mocks (6)

Intentaré algo como esto:

public class MyClass(){ public void LoadData(IHelper helper){ SomeProperty = helper.GetSomeData(); }

De esta forma puede simular la clase de ayuda usando, por ejemplo, MOQ.

Estoy tratando de encontrar una forma de falsificar el resultado de un método llamado desde otro método.

Tengo un método "LoadData" que llama a un ayudante por separado para obtener algunos datos y luego lo transformará (estoy interesado en probar el resultado transformado).

Así que tengo un código como este:

public class MyClass(){ public void LoadData(){ SomeProperty = Helper.GetSomeData(); } public object SomeProperty {get;set;} }

Quiero tener un resultado conocido del método Helper.GetSomeData (). ¿Puedo usar un marco de burla (tengo bastante experiencia con Rhino Mocks pero estoy abierto a todo) para forzar un resultado esperado? ¿Si es así, cómo?

* Editar - sí, como era de esperar no pude lograr el hack que quería, tendré que encontrar una mejor manera de configurar los datos.


Por lo que sé, debes crear una interfaz o una clase abstracta base para el objeto Helper. Con Rhino Mocks, puede devolver el valor que desee.

Alternativamente, puede agregar una sobrecarga para LoadData que acepte como parámetros los datos que normalmente recupera del objeto Helper. Esto podría ser aún más fácil.


Sí, un marco burlón es exactamente lo que estás buscando. Puede grabar / organizar cómo desea que regresen ciertas clases simuladas / rechazadas.

Rhino Mocks, Typemock y Moq son buenas opciones para hacer esto.

La publicación de Steven Walther sobre el uso de Rhino Mocks me ayudó mucho cuando empecé a jugar con Rhino Mocks.


Tienes un problema allí. No sé si ese es un escenario simplificado de tu código, pero si la clase Helper se usa de esa manera, entonces tu código no se puede probar. Primero, la clase Helper se usa directamente, por lo que no puede reemplazarla con un simulacro . Segundo, estás llamando a un método estático. No sé sobre C #, pero en Java no puede anular los métodos estáticos .

Tendrá que hacer algunas refactorizaciones para poder inyectar un objeto simulado con un método ficticio GetSomeData ().

En esta versión simplificada de su código, es difícil darle una respuesta directa. Usted tiene algunas opciones:

  • Cree una interfaz para la clase Helper y proporcione una forma para que el cliente inserte la implementación de Helper en la clase MyClass. Pero si Helper es realmente una clase de utilidad, no tiene mucho sentido.
  • Cree un método protegido en MyClass llamado getSomeData y haga que solo llame a Helper.LoadSomeData. Luego reemplace la llamada a Helper.LoadSomeData en LoadData por getSomeData. Ahora puede simular el método getSomeData para devolver el valor ficticio.

Tenga cuidado de simplemente crear una interfaz para la clase Helper e inyectarla a través del método. Esto puede exponer detalles de implementación. ¿Por qué un cliente debe proporcionar una implementación de una clase de utilidad para llamar a una operación simple? Esto aumentará la complejidad de los clientes de MyClass.


Yo recomendaría convertir lo que tienes en algo como esto:

public class MyClass() { private IHelper _helper; public MyClass() { //Default constructor normal code would use. this._helper = new Helper(); } public MyClass(IHelper helper) { if(helper == null) { throw new NullException(); //I forget the exact name but you get my drift ;) } this._helper = helper; } public void LoadData() { SomeProperty = this._helper.GetSomeData(); } public object SomeProperty {get;set;} }

Ahora su clase admite lo que se conoce como inyección de dependencia. Esto le permite inyectar la implementación de la clase auxiliar y garantiza que su clase solo dependa de la interfaz. Cuando te burles de esto, sabes que creas un simulacro que usa la interfaz IHelper y lo pasas al constructor y tu clase lo usará como si fuera la verdadera clase Helper.

Ahora bien, si está atrapado usando la clase Helper como una clase estática, le sugiero que use un patrón proxy / adaptador y ajuste la clase estática con otra clase que admita la interfaz IHelper (que también deberá crear).

Si en algún momento desea llevar esto un paso más, podría eliminar por completo la implementación de Helper predeterminada de la clase revisada y usar contenedores IoC (Inversión de control). Sin embargo, si esto es nuevo para usted, le recomendaría que se centre primero en los fundamentos de por qué todo este inconveniente adicional vale la pena (en mi humilde opinión).

Las pruebas de su unidad se parecerán a este código psuedo:

public Amazing_Mocking_Test() { //Mock object setup MockObject mockery = new MockObject(); IHelper myMock = (IHelper)mockery.createMockObject<IHelper>(); mockery.On(myMock).Expect("GetSomeData").WithNoArguments().Return(Anything); //The actual test MyClass testClass = new MyClass(myMock); testClass.LoadData(); //Ensure the mock had all of it''s expectations met. mockery.VerifyExpectations(); }

Siéntase libre de comentar si tiene alguna pregunta. (Por cierto, no tengo idea de si este código funciona, lo escribí en mi navegador, principalmente estoy ilustrando los conceptos).


Es posible que desee buscar en Typemock Isolator, que puede "falsificar" las llamadas al método sin forzarlo a refactorizar su código. Soy un desarrollador en esa compañía, pero la solución es viable si desea elegir no cambiar su diseño (u obligada a no cambiarlo para probarlo) está en www.Typemock.com

Blog de Roy: ISerializable.com