c++ - test - Función libre de burla
catch c++ unit test (1)
Estoy atrapado en un problema y no puedo encontrar la solución.
Estoy usando VS2005 SP1 para compilar el código.
Tengo una función global:
A* foo();
Tengo una clase falsa
class MockA : public A {
public:
MOCK_METHOD0 (bar, bool());
...
};
En las fuentes, se accede de esta manera: foo()->bar()
. No puedo encontrar una manera de burlarme de este comportamiento. Y no puedo cambiar las fuentes, por lo que la solución en el libro de Google Mock Cook está fuera de toda duda.
Cualquier ayuda o indicadores en la dirección correcta serán muy apreciados. :)
No, no es posible, sin cambiar las fuentes, o traer su propia versión de foo()
que esté vinculada con el código ejecutable.
De las preguntas frecuentes de GoogleMock dice
Mi código llama a una función estática / global. ¿Puedo burlarlo?
Puedes, pero necesitas hacer algunos cambios.
En general, si encuentra que necesita simular una función estática, es una señal de que sus módulos están acoplados muy estrechamente (y son menos flexibles, menos reutilizables, menos comprobables, etc.). Probablemente sea mejor que defina una interfaz pequeña y llame a la función a través de esa interfaz, que luego se puede burlar fácilmente. Inicialmente, es un poco trabajo, pero generalmente se amortiza rápidamente.
Esta publicación de Google Testing Blog lo dice de manera excelente. Echale un vistazo.
También del Cookbook
Burlarse de las funciones gratuitas
Es posible utilizar Google Mock para simular una función gratuita (es decir, una función estilo C o un método estático). Solo necesita volver a escribir su código para usar una interfaz (clase abstracta).
En lugar de llamar directamente a una función gratuita (por ejemplo, OpenFile), introduzca una interfaz para ello y tenga una subclase concreta que invoque la función gratuita:
class FileInterface { public: ... virtual bool Open(const char* path, const char* mode) = 0; }; class File : public FileInterface { public: ... virtual bool Open(const char* path, const char* mode) { return OpenFile(path, mode); } };
Su código debe hablar con FileInterface para abrir un archivo. Ahora es fácil burlarse de la función.
Esto puede parecer muy complicado, pero en la práctica a menudo tiene múltiples funciones relacionadas que puede colocar en la misma interfaz, por lo que la sobrecarga sintáctica por función será mucho menor.
Si le preocupa la sobrecarga del rendimiento que suponen las funciones virtuales, y el perfil confirma su preocupación, puede combinar esto con la fórmula para burlarse de los métodos no virtuales.
Como mencionaste en tu comentario de que en realidad proporcionas tu propia versión de foo()
, puedes resolver fácilmente esto teniendo una instancia global de otra clase falsa:
struct IFoo {
virtual A* foo() = 0;
virtual ~IFoo() {}
};
struct FooMock : public IFoo {
FooMock() {}
virtual ~FooMock() {}
MOCK_METHOD0(foo, A*());
};
FooMock fooMock;
// Your foo() implementation
A* foo() {
return fooMock.foo();
}
TEST(...) {
EXPECT_CALL(fooMock,foo())
.Times(1)
.WillOnceReturn(new MockA());
// ...
}
No se olvide de borrar todas las expectativas de llamadas, después de ejecutar cada caso de prueba.