2009-10-14 18 views
12

¿Existe alguna manera de usar simulaciones o falsificaciones en las pruebas de su unidad sin tener que usar la inyección de dependencia o la inversión o el control?Burlarse sin IoC o Inyección de Dependencia

Encontré que esta sintaxis se puede usar con TypeMock Isolator (http://learn.typemock.com/). Sin embargo, es un producto comercial, por lo que esperaba que otros marcos (como RhinoMocks) introdujeran dicha sintaxis en algún momento.

/// Can mock objects WITHOUT DEPENDENCY INJECTION. 

var hand = Isolate.Fake.Instance<Hand>(); 
var mouth = Isolate.Fake.Instance<Mouth>(); 
Isolate.Swap.NextInstance<Hand>().With(hand); 
Isolate.Swap.NextInstance<Mouth>().With(mouth); 
... 
//notice we're not passing the mocked objects in. 
var brain = new Brain(); 
brain.TouchIron(iron); 
... 

Esto es muy atractivo para mí este tipo de sintaxis, todo sucede automáticamente. Podemos crear un cerebro allí sin que se pasen las dependencias requeridas y el marco de burla sustituirá las dependencias automáticamente por los objetos simulados. Cualquier cuerpo visto este tipo de cosas en otro lugar?

El cerebro constructor de la clase tiene este aspecto ahora usando la sintaxis anterior,

public Brain() 
{ 
    _hand = new Hand(); 
    _mouth = new Mouth(); 
} 

Mientras que el ejemplo de inyección de dependencia se vería así,

public Brain(IHand hand, IMouth mouth) 
{ 
    _hand = hand; 
    _mouth = mouth; 
} 

Gracias.

Respuesta

11

Si tiene una opción, casi siempre debe exponer un constructor para permitir la inyección de dependencias. Aún se podía mantener el constructor de conveniencia (aunque se podría argumentar que no debería):

public Brain() : this(new Hand(), new Mouth()) { } 

Dicho esto, además de ISOLATOR se puede consultar las últimas compilaciones de Pex (0.17), que incluyen moles que proporcione un mecanismo similar a Isolator's Swap.

+1

De acuerdo, el reenvío de constructor predeterminado al real es una técnica muy útil. –

4

Personalmente no creo que esto sea algo bueno.

Para mí, DI ofrece más beneficios que la capacidad de prueba, por lo que es irrazonable, incluso si alguna herramienta lo permite. Consulte también this question y la primera respuesta.

+2

ABSOLUTAMENTE VERDADERO - ¡pero tenga en cuenta los millones de líneas de código heredado que pueden no ser realistas para migrar pero que podrían beneficiarse de las pruebas unitarias! – mtazva

4

AFAIK, TypeMock es el único marco que permite este escenario, y probablemente será durante mucho tiempo. La razón es que usa un enfoque radicalmente diferente a la burla.

Todos los demás marcos de burla utilizan la creación dinámica de tipos para hacer lo mismo que se puede hacer en el código: extrae y anula. En este caso, manual and dynamic mocks are basically the same thing, porque ellos confían en poder extender tipos abstractos.

TypeMock utiliza una técnica radicalmente diferente, ya que utiliza la API de perfiles .NET (no administrada) para interceptar llamadas al tipo . Esto es mucho más difícil de implementar, por lo que no debería sorprender que se trate de una empresa comercial.

En cualquier caso, TypeMock frente al resto del mundo es un debate antiguo y muy animado. Here's one take on it (asegúrese de leer también los comentarios).

2

Moles, una estructura de desvío que se envía con Pex, también permite hacer esto ... pero con una sintaxis diferente.

MHand.New = (me) => { 
    new MHand(me) { 
     TouchIronIron = iron => {} 
    };  
}; 

Tenga en cuenta que su ejemplo es incoherente.

0

Gracias por eso. Me ha dado montones en que pensar. Estoy trabajando en una aplicación que no ha sido diseñada para pruebas y que actualmente no tiene pruebas unitarias. Creo que la solución final será reestructurarlo gradualmente y usar Rhino Mocks. He usado Rhino montones antes, y ha sido genial.

He empezado a darme cuenta de que la solución 'all in' es probablemente la mejor, es decir, Rhino forzará a la reestructuración a utilizar una Inversion of Control completa que forzará buenas decisiones de diseño.

Independientemente del marco de burla que utilizo, me sentiría cómodo de que yo mismo podría tomar buenas decisiones de diseño ya que he hecho montones de trabajo como este antes, pero otros que trabajan en el código no han hecho pruebas unitarias antes, entonces el escenario que los fuerza a usar IoC es mejor.

Cuestiones relacionadas