La depresión en las respuestas es abrumadora ... Pero no temas, tenemos the holy book to exorcise the demons of legacy C++ code. En serio, solo compre el libro si está en línea durante más de una semana de justa con el código de C++ heredado.
Pasar a la página 127: El caso de las horribles incluyen dependencias. (Ahora estoy ni siquiera dentro de miles de plumas de Michael, pero aquí como corta-as-I-podría-Gestión respuesta ..)
Problema: En C++ si un classA necesita saber sobre ClassB, Clase B de la declaración se levanta directamente/se incluye textualmente en el archivo fuente de la Clase A. Y dado que a los programadores nos encanta llevarlo al extremo equivocado, un archivo puede incluir recursivamente un trillón de otros transitoriamente. Las construcciones llevan años ... pero bueno, al menos se construye ... podemos esperar.
Ahora decir 'instanciar ClassA bajo un arnés de prueba es difícil' es insuficiente. (Citando el ejemplo de MF - Scheduler es nuestro hijo poster problema con deps en abundancia.)
#include "TestHarness.h"
#include "Scheduler.h"
TEST(create, Scheduler) // your fave C++ test framework macro
{
Scheduler scheduler("fred");
}
Esto incluye llevar a cabo el dragón con una ráfaga de errores de generación.
Golpe n. ° 1 Paciencia-n-Persistencia: Tome en cada uno uno a la vez y decida si realmente necesitamos esa dependencia. Supongamos que SchedulerDisplay es uno de ellos, cuyo método displayEntry se llama en el ctor de Scheduler.
Blow # 2 falso-que-hasta-que-hacer-que (Gracias RonJ):
#include "TestHarness.h"
#include "Scheduler.h"
void SchedulerDisplay::displayEntry(const string& entryDescription) {}
TEST(create, Scheduler)
{
Scheduler scheduler("fred");
}
y pop va la dependencia y toda su transitiva incluye. También puede reutilizar los métodos falsos al encapsularlo en un archivo Fakes.h para incluirlo en los archivos de prueba.
Golpe # 3 Práctica: Puede que no sea siempre así de simple ... pero ya entiendes. Después de los primeros duelos, el proceso de ruptura deps obtendrá Easy-N-mecánica
Advertencias (¿Mencioné que hay advertencias? :)
- necesitamos una estructura separada para casos de prueba en Este archivo ; solo podemos tener 1 definición para el método SchedulerDisplay :: displayEntry en un programa.Por lo tanto, cree un programa separado para las pruebas del planificador.
- No estamos rompiendo ninguna dependencia en el programa, por lo que no estamos limpiando el código.
- Necesita mantener esas falsificaciones mientras necesitemos las pruebas.
- Su sentido de la estética puede ser ofendido por un tiempo .. sólo muerden el labio y 'oso con nosotros para un mejor mañana'
utilizar esta técnica para un muy gran clase con graves problemas de dependencia. No lo use a menudo o ligeramente. Use esto como punto de partida para refactorizaciones más profundas. Con el tiempo, este programa de prueba puede tomarse detrás del establo a medida que extrae más clases (CON sus propias pruebas).
Para obtener más información, lea el libro. Inestimable. ¡Lucha contra hermano!
Ojalá pudiera este voto positivo x 10, esta es, de lejos, la mejor pregunta sobre SO que he leído hasta ahora. He perdido la cuenta de las personas que simplemente se rinden 'No podemos probar ... tenemos código C++ .. ¡Boohoo!' – Gishu
Gishu, no podría estar más de acuerdo. Estoy teniendo las mismas discusiones aquí donde trabajo. – Lou