unit test google framework for catch c++ unit-testing

c++ - framework - google test install



Pruebas unitarias de métodos privados (8)

Estoy en el proceso de escribir algunas pruebas unitarias. En particular, quiero probar algunos métodos privados.

Hasta ahora he encontrado el uso.

#define private public

Pero no estoy contento con esto, ya que destruirá toda la encapsulación desde el punto de vista de la prueba unitaria.

¿Qué métodos usas para probar los métodos privados?


Después de muchas horas, esto es lo que decidí ser la mejor solución para aquellos que quieren probar sus funciones privadas. Esta es una combinación de respuestas de y Miloš .

Si está utilizando boost :: unit-test, entonces hay una solución fácil y elegante.

  1. Use protected lugar de private en sus clases

    /* MyClass.hpp */ class MyClass { protected: int test() { return 1; } };

  2. Crea un accesorio :

    /* TestMyClass.cpp */ class F : public MyClass {}; BOOST_FIXTURE_TEST_SUITE(SomeTests, F) // use any protected methods inside your tests BOOST_AUTO_TEST_CASE(init_test) { BOOST_CHECK_EQUAL( test(), 1 ); } BOOST_AUTO_TEST_SUITE_END()

¡De esta forma puede usar libremente cualquiera de las funciones de MyClass sin #define private public o agregar amigos a su clase!


El hack de definición es una idea horrible. Arbitrariamente volver a escribir su código con el preprocesador cuando vaya a compilarlo nunca es prudente.

Ahora, como varias personas ya lo han mencionado, es discutible si deberían probar métodos privados en absoluto. Pero esto no cubre el caso en el que intencionalmente has ocultado constructores para restringir la instanciación a ciertos ámbitos, o algunos otros casos más esotéricos.

Además, no se puede usar como amigo un espacio de nombres y la "amistad" no se hereda en C ++, por lo que, según el marco de prueba de tu unidad, podrías tener problemas. Afortunadamente, si está utilizando Boost.Test, hay una solución elegante para este problema en forma de Fixtures.

http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html

Puede hacer de amigo del dispositivo y hacer que crea una instancia de todas las instancias que utiliza en las funciones de prueba de la unidad, declarando que son estáticas para el dispositivo y con el alcance del módulo. Si está utilizando un espacio de nombres, no se preocupe, puede declarar su dispositivo dentro del espacio de nombres y sus casos de prueba fuera del espacio de nombres, y luego usar el operador de resolución del alcance para llegar a los miembros estáticos.

La macro BOOST_FIXTURE_TEST_CASE se encargará de instanciar y derribar su dispositivo por usted.


En lugar del desagradable #define que mencionas en la pregunta, un mecanismo más limpio es hacer que la prueba sea un amigo de la clase bajo prueba. Esto permite que el código de prueba (y solo el código de prueba) acceda a las partes privadas, a la vez que las protege de todo lo demás.

Sin embargo, es preferible probar a través de la interfaz pública. Si su clase X tiene una gran cantidad de código en las funciones miembro privado, entonces podría valer la pena extraer una nueva clase Y que es utilizada por la implementación de la clase X. Esta nueva clase Y puede probarse a través de su interfaz pública, sin exponer su uso para los clientes de la clase X.


Haga que la clase de prueba sea la amiga de la clase original. Esta declaración de amigo estará dentro del #define UNIT_TEST .

class To_test_class { #ifdef UNIT_TEST friend test_class; #endif }

Ahora para su prueba de unidad, compilará el código con el indicador -DUNIT_TEST . De esta forma, podrás probar la función privada.

Ahora su código de prueba unitaria no se UNIT_TEST en el entorno de producción, ya que el indicador UNIT_TEST será falso. Por lo tanto, el código sigue siendo seguro.

Además, no necesitará ninguna biblioteca especial para pruebas unitarias.


No creo que se requieran casos de prueba unitaria para métodos privados.

Si un método es privado, puede usarse solo dentro de esa clase. Si ha probado todos los métodos públicos utilizando este método privado, no es necesario probarlo por separado, ya que solo se utilizó de muchas maneras.


Sé que esta es una pregunta más antigua, pero parece que nadie ha compartido el método relativamente bueno que yo prefiero, así que aquí va:

Cambia el método que deseas probar de private a protected . Para otras clases, el método seguirá siendo private , pero ahora puede derivar una clase de "prueba" de su clase base que expone la funcionalidad privada que desea probar.

Aquí hay un ejemplo mínimo:

class BASE_CLASS { protected: int your_method(int a, int b); }; class TEST_CLASS : public BASE_CLASS { public: int your_method(int a, int b) { return BASE_CLASS::your_method(a, b); } }

Por supuesto, tendrá que actualizar sus pruebas unitarias para ejecutar sus pruebas en la clase derivada en lugar de la clase base, pero después de eso, cualquier cambio realizado en la clase base se reflejará automáticamente en la clase "prueba".


Si está usando Google Test, puede usar FRIEND_TEST para declarar fácilmente su dispositivo de prueba como amigo de la clase bajo prueba.

Y sabes, si probar las funciones privadas fuera inequívocamente malo como algunas de las otras respuestas decían, entonces probablemente no se incorporaría a Google Test.

Puede leer más sobre cuándo probar las funciones privadas es bueno o malo en esta respuesta .


Si los métodos son lo suficientemente complejos como para justificar las pruebas de forma aislada, reordenelos en su (s) propia (s) clase (s) y realice la prueba a través de su (s) interfaz (es) pública (s). Luego, utilícelos en privado en la clase original.