2011-12-01 48 views
4

我正在使用CUnit进行项目单元测试。 我需要测试是否使用正确的参数&调用libc函数,无论我是否正确地处理它们的返回值。 例如:如果我调用绑定(...)函数 - 我想检查我通过哪个af参数&断言如果这是错误的,我也想效仿它的返回值&断言如果我检查它是正确的方式。CUnit - '嘲弄'libc函数

为了这些目的,我希望CUnit环境有一个内置的机制让我在测试时调用'mocked'bind()函数,运行代码时调用一个真正的bind()函数 - 但是我可以'找到像这样的东西。

如果我在CUnit中丢失了某些东西,或者可能会提出实现方法,您可以告诉我吗?

谢谢, 乔。

回答

5

不幸的是,你不能用CUnit在C中模拟函数。

但是你可以通过使用和定义的滥用实现自己的模拟功能: 假设你编译的测试时,定义单元测试,您可以在测试文件(或在包括)定义是这样的:

#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

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