我意识到这是一个非常古老的线程,但我希望当他们遇到这个问题时,我可以让他们的生活更轻松一些。
您可以使用Mimicc轻松地为与 GoogleTest 兼容的 C 函数自动生成模拟。找到任何头文件声明您要模拟的函数,将它们“编译”成模拟实现目标文件,并将它们链接到您的测试二进制文件中,包括专门针对 Google 测试的用户指南中描述的mock_fatal()
和函数的定义。您必须使用 Mimicc API 与 Mimicc 生成的模拟交互(即它不使用 GoogleMock 的 API 来设置期望等),但它们可以舒适地与 GoogleMock 生成的模拟一起使用。mock_failure()
更具体地说,假设您有一个 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
的相同内容来为这些创建模拟:CFLAGS
foo.c
prompt$ mimicc -c foo.h -o mock.o --hout=foo-mock.h -DSOME_PREPROC=1 -I <your includes>
foo-mock.h
要在测试中使用它,请使用上面命令行调用中所示的 API 设置期望值和返回值。包括 Google Test 的实现mock_fatal()
和mock_failure()
用于 Google 测试。
#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++ 代码,而无需实际编写或维护额外的模拟代码,您只需专注于测试。从长远来看,要容易一些。