Tenho o sistema que executa o network trabalhador assíncrono e verifica periodicamente se o trabalhador tem algum std::exception_ptr
armazenado. Nesse caso, ele pode gerar ou relatar um erro de alguma outra forma. Exemplo simples:
#include <exception>
#include <gmock/gmock.h>
// simplified Network interface and the mock
struct INetwork {
virtual std::exception_ptr getExceptionPtr() const = 0;
};
struct MockedNetwork: public INetwork {
public:
MOCK_METHOD(std::exception_ptr, getExceptionPtr, (), (const override));
};
// simplified system
class System {
public:
System(INetwork& network): _network{network} {}
void run() {
// some complex logic
std::exception_ptr exPtr = _network.getExceptionPtr();
if (exPtr) {
// error handling, or just rethrow
std::rethrow_exception(exPtr);
}
}
private:
INetwork& _network;
};
Então eu gostaria de testar meu código para o seguinte cenário
Sempre que a rede relatar um erro por meio de exceção_ptr, o sistema deverá relançar esta exceção
então eu tenho este pequeno caso de teste gtest:
#include <stdexcept>
#include <gtest/gtest.h>
struct MyException: public std::runtime_error {
MyException(): std::runtime_error("MyException") {}
};
TEST(Demo, demo) {
MockedNetwork mockedNet;
EXPECT_CALL(mockedNet, getExceptionPtr()).WillRepeatedly([]() -> std::exception_ptr{
return nullptr; // this is OK, but I want to simulate an error, not error-free run
// return new MyException; // this doesn't compile, and anyway seems like a bad idea
});
System sut(mockedNet);
ASSERT_THROW(sut.run(), MyException);
}
Como posso simular a situação em que minha rede simulada retorna std::exception_ptr
contendo um ponteiro para minha exceção personalizada que pode ser lançada novamente?
std::make_exception_ptr
:No final acabou sendo bastante simples. Na configuração do teste, você pode simplesmente lançar uma exceção dentro do
try
bloco, capturá-la, armazená-lastd::exception_ptr
e usá-la na ação gmock:Isso funciona, mas talvez existam outras maneiras melhores e/ou mais interessantes de obter o mesmo efeito.