2011-12-01 84 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)); 
}