我意识到这是一个非常古老的话题,但我希望当他们遇到这个问题时,我可以让他们的生活变得更轻松。
您可以使用Mimicc 轻松地为与 GoogleTest 兼容的 C 函数自动生成模拟。查找任何头文件声明您要模拟的函数,将它们“编译”为模拟实现目标文件,并将它们链接到您的测试二进制文件中,包括mock_fatal() 和mock_failure() 函数的定义,如User Guide 中所述,专门针对谷歌测试。您必须使用 Mimicc API 与 Mimicc 生成的模拟进行交互(即它不使用 GoogleMock 的 API 来设置期望等),但它们可以舒适地与 GoogleMock 生成的模拟一起使用。
更具体地说,假设你有一个 C 头文件 foo.h,它声明了一些你想模拟的函数。例如:
/*!
* @param[out] pBuf Destination buffer to read to
* @param[in] sz Size of the read buffer
*/
int magic_read(char *pBuf, const size_t sz);
/*!
* @param[in] pBuf Source buffer to write from
* @param[in] sz Size of the write buffer
*/
int magic_write(const char *pBuf, const size_t sz);
您可以通过编译 foo.h 和用于编译随附产品 foo.c 的所有相同的 CFLAGS 来为这些创建模拟:
prompt$ mimicc -c foo.h -o mock.o --hout=foo-mock.h -DSOME_PREPROC=1 -I <your includes>
要在测试中使用它,请使用foo-mock.h 中声明的 API 设置期望值和返回值,如上面的命令行调用所示。包括对 Google 测试的 mock_fatal() 和 mock_failure() 的实现。
#include <gtest/gtest.h>
#include <memory>
std::unique_ptr<char []> mockErrStr(const char *pLocation, unsigned count, const char *pMsg)
{
const char *pFmtStr = "mock assertion failure! location: '%s',"
" iteration: %d, message: %s";
size_t n = snprintf(NULL, 0, pFmtStr, pLocation, count, pMsg);
std::unique_ptr<char []> outStrBuf(new char[n+1]);
snprintf(outStrBuf.get(), n+1, pFmtStr, pLocation, count, pMsg);
return outStrBuf;
}
void mock_failure(const char *pLocation, unsigned count, const char *pMsg)
{
ADD_FAILURE() << mockErrStr(pLocation, count, pMsg).get();
}
void mock_fatal(const char *pLocation, unsigned count, const char *pMsg)
{
FAIL() << mockErrStr(pLocation, count, pMsg).get();
exit(1);
}
TEST_F(MimiccPoC, test1)
{
char mock_ret_data[] = "HELLO WORLD";
MOCK_FUNCTIONS(foo).magic_read.expect(32);
MOCK_FUNCTIONS(foo).magic_read.andReturn(
1, mock_ret_data, sizeof(mock_ret_data));
char testRetBuf[32];
int testRes = magic_read(testRetBuf, sizeof(testRetBuf));
ASSERT_EQ(1, testRes);
ASSERT_STREQ(testRetBuf, "HELLO WORLD");
}
虽然这看起来很多,但一旦设置好管道,您就可以自动模拟您拥有的任何 C 或 C++ 代码,而无需实际编写或维护额外的模拟代码,您只需专注于测试。从长远来看会容易一些。