Me pregunto cómo usar NUnit correctamente. Primero, creé un proyecto de prueba separado que usa mi proyecto principal como referencia. Pero en ese caso, no puedo probar métodos privados. ¡¿Mi suposición fue que necesito incluir mi código de prueba en mi código principal ?! - Esa no parece ser la forma correcta de hacerlo. (No me gusta la idea de enviar un código con pruebas).
¿Cómo se prueban los métodos privados con NUnit?
c#
unit-testing
testing
nunit
Señor Fox
fuente
fuente
System.Reflection
le permite acceder e invocar métodos no públicos utilizando indicadores vinculantes, por lo que podría piratear NUnit o configurar su propio marco. O (más fácil, creo), podría configurar un indicador de tiempo de compilación (#if TESTING) para cambiar los modificadores de acceso, lo que le permite usar los marcos existentes.Si bien estoy de acuerdo en que el enfoque de las pruebas unitarias debe ser la interfaz pública, obtendrá una impresión mucho más granular de su código si también prueba métodos privados. El marco de prueba de MS permite esto mediante el uso de PrivateObject y PrivateType, NUnit no. Lo que hago en cambio es:
De esta manera, no tiene que comprometer la encapsulación a favor de la capacidad de prueba. Tenga en cuenta que deberá modificar sus BindingFlags si desea probar métodos estáticos privados. El ejemplo anterior es solo un ejemplo de métodos.
fuente
Un patrón común para escribir pruebas unitarias es probar solo métodos públicos.
Si encuentra que tiene muchos métodos privados que desea probar, normalmente esto es una señal de que debe refactorizar su código.
Sería incorrecto hacer públicos estos métodos en la clase donde viven actualmente. Eso rompería el contrato que quieres que tenga esa clase.
Puede ser correcto moverlos a una clase de ayuda y hacerlos públicos allí. Es posible que su API no exponga esta clase.
De esta manera, el código de prueba nunca se mezcla con su código público.
Un problema similar es probar clases privadas, es decir. clases que no exporta desde su ensamblado. En este caso, puede hacer explícitamente que su ensamblado de código de prueba sea un amigo del ensamblado de código de producción utilizando el atributo InternalsVisibleTo.
fuente
Es posible probar métodos privados declarando su ensamblado de prueba como ensamblado amigo del ensamblado de destino que está probando. Consulte el enlace a continuación para obtener más detalles:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
Esto puede ser útil ya que en su mayoría separa su código de prueba de su código de producción. Yo nunca he usado este método, ya que nunca lo he necesitado. Supongo que podría usarlo para probar y probar casos de prueba extremos que simplemente no puede replicar en su entorno de prueba para ver cómo lo maneja su código.
Sin embargo, como se ha dicho, realmente no debería necesitar probar métodos privados. Es más que probable que desee refactorizar su código en bloques de construcción más pequeños. Un consejo que podría ayudarte cuando llegues a refactorizar es intentar pensar en el dominio con el que se relaciona tu sistema y pensar en los objetos 'reales' que habitan en este dominio. Sus objetos / clases en su sistema deben relacionarse directamente con un objeto real, lo que le permitirá aislar el comportamiento exacto que debe contener el objeto y también limitar las responsabilidades de los objetos. Esto significará que está refactorizando lógicamente en lugar de solo hacer posible probar un método en particular; podrá probar el comportamiento de los objetos.
Si aún siente la necesidad de realizar pruebas internas, es posible que también desee considerar burlarse en sus pruebas, ya que es probable que desee centrarse en una pieza de código. La burla es donde se inyectan las dependencias de un objeto, pero los objetos inyectados no son los objetos "reales" o de producción. Son objetos ficticios con comportamiento codificado para facilitar el aislamiento de errores de comportamiento. Rhino.Mocks es un popular marco de trabajo gratuito que esencialmente escribirá los objetos por usted. TypeMock.NET (un producto comercial con una edición comunitaria disponible) es un marco más potente que puede simular objetos CLR. Muy útil para burlarse de las clases SqlConnection / SqlCommand y Datatable, por ejemplo, al probar una aplicación de base de datos.
Esperamos que esta respuesta le brinde un poco más de información para informarle sobre las pruebas unitarias en general y ayudarlo a obtener mejores resultados de las pruebas unitarias.
fuente
Estoy a favor de tener la capacidad de probar métodos privados. Cuando se inició xUnit, estaba destinado a probar la funcionalidad después de que se escribió el código. Probar la interfaz es suficiente para este propósito.
Las pruebas unitarias han evolucionado hasta convertirse en un desarrollo impulsado por pruebas. Tener la capacidad de probar todos los métodos es útil para esa aplicación.
fuente
Esta pregunta está en sus años avanzados, pero pensé en compartir mi forma de hacer esto.
Básicamente, tengo todas mis clases de prueba unitaria en el ensamblado que están probando en un espacio de nombres 'UnitTest' debajo del 'predeterminado' para ese ensamblado; cada archivo de prueba está envuelto en un:
block, y todo eso significa que a) no se está distribuyendo en una versión yb) puedo usar declaraciones
internal
/Friend
level sin saltar el aro.La otra cosa que ofrece, más pertinente a esta pregunta, es el uso de
partial
clases, que se pueden usar para crear un proxy para probar métodos privados, por ejemplo, para probar algo como un método privado que devuelve un valor entero:en las clases principales del ensamblado y la clase de prueba:
Obviamente, debe asegurarse de no usar este método durante el desarrollo, aunque una versión de lanzamiento pronto indicará una llamada inadvertida si lo hace.
fuente
El objetivo principal de las pruebas unitarias es probar los métodos públicos de una clase. Esos métodos públicos utilizarán esos métodos privados. Las pruebas unitarias probarán el comportamiento de lo que está disponible públicamente.
fuente
Disculpe si esto no responde a la pregunta, pero soluciones como usar la reflexión, # si las declaraciones #endif o hacer visibles los métodos privados no resuelven el problema. Puede haber varias razones para no hacer visibles los métodos privados ... ¿qué pasa si es código de producción y el equipo está escribiendo pruebas unitarias retrospectivamente, por ejemplo?
Para el proyecto en el que estoy trabajando, solo MSTest (lamentablemente) parece tener una forma, usando accesores, para probar unitarios métodos privados.
fuente
No pruebas funciones privadas. Hay formas de utilizar la reflexión para entrar en métodos y propiedades privados. Pero eso no es realmente fácil y desaconsejo esta práctica.
Simplemente no debes probar nada que no sea público.
Si tiene algunos métodos y propiedades internos, debería considerar cambiar eso a público o enviar sus pruebas con la aplicación (algo que realmente no veo como un problema).
Si su cliente puede ejecutar un Test-Suite y ve que el código que entregó en realidad "funciona", no veo esto como un problema (siempre y cuando no revele su IP a través de esto). Las cosas que incluyo en cada lanzamiento son informes de prueba e informes de cobertura de código.
fuente
En teoría de las pruebas unitarias, solo se debe probar el contrato. es decir, solo miembros públicos de la clase. Pero en la práctica, el desarrollador generalmente quiere probar miembros internos para. - y no está mal. Sí, va en contra de la teoría, pero en la práctica puede ser útil a veces.
Entonces, si realmente desea probar miembros internos, puede usar uno de estos enfoques:
Ejemplo de código (pseudocódigo):
fuente
Message: Method is not public
.Puede hacer que sus métodos estén protegidos de forma interna y luego usarlos
assembly: InternalsVisibleTo("NAMESPACE")
en su espacio de nombres de prueba.Por lo tanto, ¡NO! No puede acceder a métodos privados, pero esto es una solución.
fuente
Haría visible el paquete de métodos privados. De esa manera, lo mantendrá razonablemente privado y al mismo tiempo podrá probar esos métodos. No estoy de acuerdo con la gente que dice que las interfaces públicas son las únicas que deberían probarse. A menudo hay un código realmente crítico en los métodos privados que no se pueden probar correctamente pasando solo por las interfaces externas.
Así que realmente se reduce a si te importa más el código correcto o la ocultación de información. Yo diría que la visibilidad del paquete es un buen compromiso, ya que para acceder a esos métodos, alguien tendría que colocar su clase en su paquete. Eso realmente debería hacerlos pensar dos veces sobre si es algo realmente inteligente.
Por cierto, soy un tipo de Java, por lo que la visibilidad del paquete podría llamarse algo completamente diferente en C #. Basta decir que es cuando dos clases tienen que estar en el mismo espacio de nombres para poder acceder a esos métodos.
fuente