¿Por qué los atributos de prueba de unidad generalmente requieren métodos públicos?

12

Hace poco noté que no se respetaba agregar [TestInitialize] a un método protegido en un ensamblado .NET, pero si hacía público el método, el corredor de prueba de la unidad lo llamaba (Resharper en este caso). He notado esto varias veces en el pasado con métodos de prueba.

Técnicamente hablando, es tan fácil reflexionar sobre un método privado como un método público. De hecho, la reflexión es un método empleado para probar métodos privados.

Entonces, ¿por qué necesito hacer públicos todos los métodos de prueba de mi unidad?

Justin Dearing
fuente
2
Esa es una muy buena pregunta. El único buen argumento que he escuchado es que sigue el principio "programa a una interfaz, no a una implementación", parte de los principios SOLID.
Robert Harvey
99
No creo que esté hablando de probar sus clases, está hablando de los métodos de prueba reales que son llamados por el marco de prueba.
jtiger
1
@RobertHarvey en Java, una razón para una restricción similar (por ejemplo, en JUnit) es que los diseñadores de marcos no quieren meterse con algo setAccessibleque puede ser bloqueado por un SecurityManager personalizado
mosquito
1
debe tener en cuenta que esta decisión de diseño se tomó para un marco de propósito general dirigido a un amplio uso. En casos como ese, es más seguro para el diseñador asumir y prepararse para lo peor. Si se trata, no sé, de un marco interno de la empresa (donde se puede tener la oportunidad de garantizar las políticas de seguridad deseadas), o si se tratara de una herramienta de propósito limitado y especializado (piense "espectador para miembros inaccesibles"), diseñador tendría otras opciones para considerar
mosquito
2
@GregBurghardt Este comportamiento se encuentra en Nunit, y probablemente otros marcos de prueba que Microsoft no escribió. Claro, en los años transcurridos desde que hice esta pregunta, entiendo mucho más sobre .NET, pero sigo pensando que es una pregunta justa, y hay una buena discusión en los comentarios.
Justin Dearing

Respuestas:

2

Debe probar lo que la clase lo hace , no cómo lo hace.

En lo que respecta al "mundo exterior", eso es lo que la clase ponga a disposición del público; su marco de prueba está haciendo la misma suposición.

Al probar algo "menos" que Público, está profundizando en la implementación interna de la clase, que es una mala idea.

Phill W.
fuente
Tenga en cuenta que la pregunta se refiere a los métodos de prueba y no a los métodos del sistema bajo prueba. Si bien es cierto que OP argumenta que puede usar la reflexión para probar cosas "menos" que lo público, es un argumento sobre la capacidad de los marcos de prueba para acceder a métodos privados. El marco de prueba tiene que usar la reflexión para encontrar los métodos de prueba (que están marcados por un atributo) y, por lo tanto, debe usar la reflexión, con eso en mente ... "¿por qué necesito hacer públicos todos los métodos de prueba de mi unidad?"
Theraot
Los métodos de prueba tienen la capacidad de acceder a métodos privados; Con Reflection, todo es posible. Veo esta pregunta más sobre la [no] conveniencia de hacerlo.
Phill W.
0

Como regla general, es mejor acceder solo a métodos públicos: cuando crea una clase, también está creando el contrato sobre qué otras clases deberían acceder a su código. Entonces, la respuesta es más probable solo porque es una convención.

Vetle
fuente
1
Esto realmente no responde la pregunta.
RubberDuck