Pregunta

Suponga que tiene una clase Foo con miembros privados de tipo barra. Usted no desea que los usuarios sepan que la aplicación de Foo contiene un bar y que no desea que los usuarios puedan crear su propio bar y pasarlo por el constructor de Foo, cualquier otro método, o un archivo de configuración.

Editar: Bar. También es problemático, ya que accede a recursos fuera del control de su entorno de prueba, tales como una base de datos especial, conexión de red, u otro proceso

¿Qué hacer cuando usted también quiere ser capaz de Foo prueba de unidad? Es la inyección de dependencia todavía es posible? ¿Quiere decir esto bar y Foo están demasiado estrechamente acoplada (a pesar de que la dependencia es una manera) y que esta situación no es un uno aceptable para estar en?

¿Fue útil?

Solución

[Descargo de responsabilidad: yo trabajo en Typemock ]

Hay tres alternativas:

  1. Crea un método interno que establece la clase Bar -. InternalVisibleTo utilizando en los assemblyInf.cs archivo que puede permitir que sus pruebas para establecer esa clase
  2. Uso DI para inyectar la clase de bar, durante la prueba de cambiar esa clase con un maniquí o falso.
  3. Uso Falsificación / Burlándose marco como Typemock aislador (NET) que permiten configurar el comportamiento falso en objetos creados dentro de otra clase usando Isolate.Swap.NextInstance<Bar>.With(fakeBar);

Otros consejos

Nunca se desea ocultar dependencias si puede evitarlo.

Si es su código, se debe hacer la dependencia explícita mediante el rediseño de Bar para aceptar los objetos producidos por el recurso caro en lugar de acceder al recurso caro directamente: mover el código de acceso de base de datos (o lo que sea) de Bar y en Foo, donde se puede inyectar dobles de prueba.

Si eso no es práctico (es decir, que está tratando con clases de otra persona), lista de Dror es muy bueno.

Si el tipo de bar es sólo un detalle de implementación de Foo, a continuación, las pruebas unitarias no tienen que preocuparse por la creación Bares, ya que sólo deben ejercer la interfaz pública de Foo todos modos.

EDIT:. Si Bar accede a los recursos externos a continuación, que lo haría una dependencia explícita para Foo y luego requerir una instancia que se pasa en el constructor de Foo que luego podría ser burlado fácilmente para pruebas unitarias

Su problema no es que se necesita para acceder a un miembro privado. Esto es sólo un síntoma de que la clase en cuestión No está diseñado para ser aislado . Se permite sólo un uso muy específico, que es new un objeto que va a un recurso caro.

Incluso si usted tiene éxito en la piratería alrededor del diseño no comprobable, que todavía sólo va a hacer las pruebas de integración. Las pruebas unitarias son alrededor de aislamiento, que es lo contrario de la integración. Dado que la clase no se puede aislar, por definición, no puede unidad de prueba.

¿Hay una razón por la que la externalización de la dependencia no es deseable? ¿Qué pasa con este objeto la exime de ser la dependencia de inyección como cualquier otro?

Editar

Me doy cuenta, por supuesto, que puede aislarlo con un poco de engaño. Sin embargo, esas técnicas de derivación interfaces públicas, lo que limita la flexibilidad futura y el aumento de la probabilidad de que alguien va a romperla (básicamente, anulando la utilidad de los miembros privados).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top