C++ CUnit-和#x27;嘲弄';libc函数
我正在使用CUnit进行项目单元测试。 我需要测试我是否使用正确的参数调用libc函数&我是否以正确的方式处理它们的返回值。 例如:如果我调用bind(…)函数,我想检查我传递了哪个af参数&如果这是错误的,我想模拟它的返回值&如果我以正确的方式检查它,我想断言它 出于这些目的,我希望CUnit环境有一个内置机制,让我在测试时调用一个“模拟的”bind()函数,在运行代码时调用一个真正的bind()函数,但我找不到类似的东西 你能告诉我我在CUnit中是否遗漏了什么,或者建议一种实现方法吗 谢谢,C++ CUnit-和#x27;嘲弄';libc函数,c++,c,unit-testing,cppunit,cunit,C++,C,Unit Testing,Cppunit,Cunit,我正在使用CUnit进行项目单元测试。 我需要测试我是否使用正确的参数调用libc函数&我是否以正确的方式处理它们的返回值。 例如:如果我调用bind(…)函数,我想检查我传递了哪个af参数&如果这是错误的,我想模拟它的返回值&如果我以正确的方式检查它,我想断言它 出于这些目的,我希望CUnit环境有一个内置机制,让我在测试时调用一个“模拟的”bind()函数,在运行代码时调用一个真正的bind()函数,但我找不到类似的东西 你能告诉我我在CUnit中是否遗漏了什么,或者建议一种实现方法吗 谢谢
不幸的是,您不能用CUnit模拟C中的函数 但您可以通过使用和滥用定义来实现自己的模拟函数: 假设在编译测试时定义了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);
}
是一个模拟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));
}
#包括“got_hook.h”
#包括“gmock/gmock.h”
#包括“gtest/gtest.h”
#包括
#包括
#包括
结构模拟绑定{
MOCK_METHOD3(Bind,int(int,const struct sockaddr*,socklen_t));
};
静态MockBind*g_mock{nullptr};
静态int绑定(int-sockfd,常量结构sockaddr*addr,socklen\u t addrlen){
返回g_mock->Bind(sockfd、addr、addrlen);
}
静态std::mutex g_test_mutex;
测试(绑定测试、模拟样本){
std::锁\保护锁(g \测试\互斥);
std::unique_ptr mock(g_mock=new MockBind());
测试:GotHook got_hook;
断言失败(got_hook.MockFunction(“bind”,(void*)&bind));
//…在此处进行测试,例如:
结构sockaddr*addr=nullptr;
EXPECT_CALL(*g_mock,Bind(1,addr,20)).WillOnce(testing::Return(0));
期望q(0,bind(1,addr,20));
}