CUNIT - 'MOSCOMing' функции LIBC
-
26-10-2019 - |
Вопрос
Я использую Cunit для тестирования модуля проекта. Мне нужно проверить, называю ли я функциям LIBC с правильными параметрами и правильно обращаюсь с их возвращающими значениями. Например: если я вызову функцию Bind (...) - я хотел бы проверить, какой AF Param я передаю и утверждаю, если это неправильно, а также я хотел бы подражать его возвращению и утверждаю, если проверю это правильный путь.
Для этих целей я ожидаю, что в среде CUNIT будет встроенный механизм, позволяющий мне назвать функцию «насмешливого» bind () во время тестирования и функции Real Bind () при запуске кода - но я не могу найти ничего подобного это.
Не могли бы вы сказать мне, если я что -то упускаю в CUNIT, или, возможно, предложить способ реализовать это.
Спасибо, Джо.
Решение
К сожалению, вы не можете издеваться над функциями в C с CUNIT.
Но вы можете реализовать свои собственные фиктивные функции, используя и злоупотребляя определениями: при условии, что вы определяете Unittest при компиляции для тестов, вы можете в тестируемом файле (или в включении) определить что -то вроде этого:
#ifdef UNITTEST
#define bind mock_bind
#endif
В файле mock_helper.c, который вы будете компилироваться в тестовом режиме:
static int mock_bind_return; // maybe a more complete struct would be usefull here
static int mock_bind_sockfd;
int mock_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
CU_ASSERT_EQUAL(sockfd, mock_bind_sockfd);
return mock_bind_return;
}
Затем в вашем тестовом файле:
extern int mock_bind_return;
extern int mock_bind_sockfd;
void test_function_with_bind(void)
{
mock_bind_return = 0;
mock_bind_sockfd = 5;
function_using_bind(mock_bind_sockfd);
}
Другие советы
Glibcmock является решением издевательской функции LIBC с Google Test. Анкет Например:
#include "got_hook.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <sys/socket.h>
#include <mutex>
#include <memory>
struct MockBind {
MOCK_METHOD3(Bind, int(int, const struct sockaddr*, socklen_t));
};
static MockBind *g_mock{nullptr};
static int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
return g_mock->Bind(sockfd, addr, addrlen);
}
static std::mutex g_test_mutex;
TEST(BindTest, MockSample) {
std::lock_guard<std::mutex> lock(g_test_mutex);
std::unique_ptr<MockBind> mock(g_mock = new MockBind());
testing::GotHook got_hook;
ASSERT_NO_FATAL_FAILURE(got_hook.MockFunction("bind", (void*)&Bind));
// ... do your test here, for example:
struct sockaddr* addr = nullptr;
EXPECT_CALL(*g_mock, Bind(1, addr, 20)).WillOnce(testing::Return(0));
EXPECT_EQ(0, bind(1, addr, 20));
}