В этом случае вам не нужно издеваться над getaddrinfo
, скорее, вам нужно тестировать, не полагаясь на его функциональность. У Патрика и Ноа есть хорошие очки, но у вас есть как минимум два других варианта:
Вариант 1: Подкласс для тестирования
Поскольку у вас уже есть свой объект в классе, вы можете тестировать подкласс. Например, предположим, что фактический класс является следующим:
class DnsClass {
int lookup(...);
};
int DnsClass::lookup(...) {
return getaddrinfo(...);
}
Затем, для тестирования, вы бы подклассы вроде этого:
class FailingDnsClass {
int lookup(...) { return 42; }
};
Теперь вы можете использовать подкласс FailingDnsClass
для генерации ошибок, но при этом проверить, что все работает правильно, когда возникает ошибка. В этом случае инъекция зависимости часто является вашим другом.
ПРИМЕЧАНИЕ. Это очень похоже на ответ Патрика, но не предполагает (надеюсь) изменения производственного кода, если вы еще не настроены на внедрение зависимостей.
Вариант 2: использовать шов ссылки
В C ++ у вас также есть швы во время компоновки, которые Майкл Фезерс описывает в Эффективная работа с устаревшим кодом .
Основная идея - использовать компоновщик и вашу систему сборки. При составлении модульных тестов, укажите в вашей собственной версии getaddrinfo
, которая будет иметь приоритет над версией системы. Например:
test.cpp:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <iostream>
int main(void)
{
int retval = getaddrinfo(NULL, NULL, NULL, NULL);
std::cout << "RV:" << retval << std::endl;
return retval;
}
lib.cpp:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res
)
{
return 42;
}
А потом для тестирования:
$ g++ test.cpp lib.cpp -o test
$ ./test
RV:42