2011-12-01 4 views
4

내 프로젝트 단위 테스트를 위해 CUnit을 사용하고 있습니다. 올바른 값을 올바르게 처리하는지 여부에 관계없이 올바른 매개 변수 &으로 libc 함수를 호출하는지 테스트해야합니다. 예를 들어, : bind (...) 함수를 호출하면 - af 매개 변수 중 하나를 확인하고 싶습니다. &이 잘못된 것이고 assert를 지정하면 반환 값 &을 에뮬레이트하고 싶습니다. 올바른 방법.CUnit - 'Mocking'libc functions

이러한 목적으로 테스트 할 때 '조롱 된'bind() 함수를 호출하고 코드를 실행할 때 실제 bind() 함수를 호출 할 수있는 기본 제공 메커니즘이 CUnit 환경에 있어야합니다. 이런 것을 찾지 마라.

내가 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

glibcmockGoogle Test과 조롱 libc 함수의 솔루션입니다. 예 :

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