Cómo utilizar gmock SaveArgPointee con std::shared_ptr de una clase derivada.
Tengo una clase BaseMessage
de la cual derivan varias subclases diferentes de DerivedMessage
y quiero enviarlas de esta manera:
class BaseMessage {
public:
virtual std::vector<uint8_t> data() const noexcept = 0;
virtual ~BaseMessage() = default;
[...]
}
class DerivedMessage : public BaseMessage {
public:
[...]
std::vector<uint8_t> data() const noexcept override { return m_data; }
private:
std::vector<uint8_t> m_data;
}
// simplificado
class Tcp {
public
virtual void sendMessage(std::shared_ptr<BaseMessage> msg) { write(msg->data());}
[...]
};
class SomeClass {
public:
SomeClass(Tcp& tcp) : m_tcp(tcp) {}
void writeDataToRemote(std::shared_ptr<DerivedMessage> derived) const {
m_tcp.sendMessage(derived);}
private:
Tcp m_tcp;
}
};
Ahora quiero escribir pruebas para la clase SomeClass
con gtest.
Por lo tanto, simulo la función de la clase TCP:
class MockTcp : public Tcp {
MOCK_METHOD(void, sendMessage, (std::shared_ptr
[...]
}
Supongamos que todo está simplificado hasta aquí pero funciona.
Entonces, en la prueba, me gustaría examinar el argumento dado a sendMessage
en la función writeDataToRemote
.
He leído sobre ::testing::SaveArg
y ::testing::SaveArgPointee
en StackOverflow (pero no en la documentación, sin embargo).
TEST(SomeClassTest, writesMessageToSocket){
MockTcp mockTcp;
SomeClass sc(mockTcp);
// >>>¿cómo declarar msgArg aquí?<<<
EXPECT_CALL(mockTcp, sendMessage()).Times(1).WillOnce(::testing::SaveArgPointee<0>(msgArg));
const auto derivedMsg = std::make_shared<DerivedMessage>();
sc.writeDataToRemote(derivedMsg);
// sigue una inspección posterior de msgArg
}
Como se escribe en el comentario del código, no sé cómo declarar la variable msgArg
para que pueda recibir el argumento real dado a sendMessage
. Cuando uso SaveArg
, creo que obtendría un puntero colgante y al hacerlo como se indica arriba, obtengo errores porque el mensaje no se puede copiar-asignar. Cualquier sugerencia sería apreciada.
davy.ai
Para declarar la variable
msgArg
para que pueda ser asignada al argumento real dado asendMessage
, se puede utilizar la funciónSaveArgPointee
proporcionada por GoogleMock.Aquí hay un ejemplo de cómo se puede modificar la prueba para declarar
msgArg
:Este código declara
msgArg
comostd::shared_ptr<basemessage>
, que es el tipo de argumento quesendMessage
espera. Luego, en la declaraciónEXPECT_CALL
,SaveArgPointee<0>(&msgArg)
guarda un puntero al objeto apuntado por el primer argumento de la función simulada enmsgArg
.Tenga en cuenta que
SaveArgPointee
toma un puntero a la variable donde se debe guardar el argumento. Aquí, proporcionamos&msgArg
para obtener su dirección.Después de que la prueba se completa, se puede inspeccionar el objeto apuntado en
msgArg
para verificar que se haya enviado elDerivedMessage
correcto.