CUnit - 'Mocking' функции libc - PullRequest
       25

CUnit - 'Mocking' функции libc

4 голосов
/ 01 декабря 2011

Я использую CUnit для тестирования моего проекта. Мне нужно проверить, вызываю ли я функции libc с правильными параметрами и правильно ли я отношусь к их возвращаемым значениям. например: если я вызываю функцию bind (...) - я хотел бы проверить, какой параметр я передаю и утверждаю, если это неправильный параметр, а также я хотел бы эмулировать его возвращаемое значение и утверждать, если я его проверяю правильный путь.

Для этих целей я бы ожидал, что в среде CUnit будет встроен механизм, позволяющий мне вызывать «mocked» функцию bind () во время тестирования, и настоящую функцию bind () при выполнении кода - но я не могу найди что-нибудь подобное.

Можете ли вы сказать мне, если я что-то упустил в CUnit, или, может быть, предложить способ реализовать это.

Спасибо, Джо.

Ответы [ 2 ]

5 голосов
/ 01 декабря 2011

К сожалению, вы не можете смоделировать функции в 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);
}
0 голосов
/ 12 марта 2017

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));
}
...