Google Test 中的期望存储在哪里?
Where expectations are stored in Google Test?
我在 CookBook 和 Google 测试框架教程的高级部分都找不到它。例如,我有以下创建期望的函数:
void testFunc()
{
for (std::size_t i = 0; i < 10; i++)
EXPECT_CALL(dummyMock, mockFunc).WillOnce(Return(i))
}
然后我在一些测试用例中调用这个函数
TEST(UnitTestCase, TestSomeMockFunc)
{
TestSomeFunction();
testFunc();
}
问题是Google Test 如何执行来自testFunc 的代码。它在 TestSomeFunction 执行后是否成功?或者在它之前,例如在编译期间?最后,在执行此函数后,来自 testFunc 的每个 "EXPECT_CALL" 语句存储在哪里?
我会尝试一一回答您的问题,然后再继续处理您的代码片段中的问题。
问题是GoogleTest如何执行testFunc的代码。
它没有。这部分就像任何 C++ 代码一样工作。首先调用 TestSomeFunction()
,然后调用 testFunc()
,循环运行 10 次。这里没有什么异常。
TestSomeFunction执行后是否成功?
是的,因为 testFunc()
在 TestSomeFunction()
之后调用。函数是按顺序调用的,Google理论上 Mock 可以应用一些宏魔法,但事实并非如此。
或者在它之前,例如在编译期间?
EXPECT_CALL
宏在编译前的预处理阶段展开。无论它下面是什么,都会在运行时执行,就像任何其他函数一样。
最后,testFunc 中的每个 "EXPECT_CALL" 语句在执行此函数后存储在哪里?
我不知道,但很可能它以某种方式存储在模拟对象中(即 dummyMock
)。我相信它在那里,因为所有期望都在模拟的析构函数中得到验证。
现在,关于第一个片段,这是 GoogleMock 的一个功能,我发现在大多数情况下它比有用更烦人。
for (std::size_t i = 0; i < 10; i++)
EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i))
以上代码创建了 10 个调用期望,但是 较新的调用期望覆盖了以前的 。因此,如果您的代码将继续调用 mockFunc
10 次,您将有 9 个未调用的期望和 1 个调用 10 次的期望(同样失败,它需要单次调用)。
如果您不需要每次调用 return 不同的值,只需使用
EXPECT_CALL(dummyMock, mockFunc()).Times(10).WillRepeatedly(Return(0));
但是,如果您每次都需要不同的值,则需要考虑的事项很少:
- 使用
RetiresOnSaturation()
- 将其添加为链中的最后一个调用(在 WillRepeatedly()
之后)。这将使您避免隐藏以前的期望的问题,因为每个期望在实现后都会被忽略。
- 添加期望的相反顺序。 - GoogleMock 以后进先出 (LIFO) 的方式添加新的期望。这意味着最新创建的期望将首先匹配(并执行)。
因此,要创建 GoogleMock 期望,使其在每次函数调用时都会 return 下一个数字,以下代码应该有效:
void testFunc()
{
for (std::size_t i = 9; i >= 0; i++)
EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i)).RetiresOnSaturation();
}
当然,在测试代码中调用模拟函数之前应该设置预期,因为否则Google模拟将不知道你打算做这样的事情.
我在 CookBook 和 Google 测试框架教程的高级部分都找不到它。例如,我有以下创建期望的函数:
void testFunc()
{
for (std::size_t i = 0; i < 10; i++)
EXPECT_CALL(dummyMock, mockFunc).WillOnce(Return(i))
}
然后我在一些测试用例中调用这个函数
TEST(UnitTestCase, TestSomeMockFunc)
{
TestSomeFunction();
testFunc();
}
问题是Google Test 如何执行来自testFunc 的代码。它在 TestSomeFunction 执行后是否成功?或者在它之前,例如在编译期间?最后,在执行此函数后,来自 testFunc 的每个 "EXPECT_CALL" 语句存储在哪里?
我会尝试一一回答您的问题,然后再继续处理您的代码片段中的问题。
问题是GoogleTest如何执行testFunc的代码。
它没有。这部分就像任何 C++ 代码一样工作。首先调用 TestSomeFunction()
,然后调用 testFunc()
,循环运行 10 次。这里没有什么异常。
TestSomeFunction执行后是否成功?
是的,因为 testFunc()
在 TestSomeFunction()
之后调用。函数是按顺序调用的,Google理论上 Mock 可以应用一些宏魔法,但事实并非如此。
或者在它之前,例如在编译期间?
EXPECT_CALL
宏在编译前的预处理阶段展开。无论它下面是什么,都会在运行时执行,就像任何其他函数一样。
最后,testFunc 中的每个 "EXPECT_CALL" 语句在执行此函数后存储在哪里?
我不知道,但很可能它以某种方式存储在模拟对象中(即 dummyMock
)。我相信它在那里,因为所有期望都在模拟的析构函数中得到验证。
现在,关于第一个片段,这是 GoogleMock 的一个功能,我发现在大多数情况下它比有用更烦人。
for (std::size_t i = 0; i < 10; i++)
EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i))
以上代码创建了 10 个调用期望,但是 较新的调用期望覆盖了以前的 。因此,如果您的代码将继续调用 mockFunc
10 次,您将有 9 个未调用的期望和 1 个调用 10 次的期望(同样失败,它需要单次调用)。
如果您不需要每次调用 return 不同的值,只需使用
EXPECT_CALL(dummyMock, mockFunc()).Times(10).WillRepeatedly(Return(0));
但是,如果您每次都需要不同的值,则需要考虑的事项很少:
- 使用
RetiresOnSaturation()
- 将其添加为链中的最后一个调用(在WillRepeatedly()
之后)。这将使您避免隐藏以前的期望的问题,因为每个期望在实现后都会被忽略。 - 添加期望的相反顺序。 - GoogleMock 以后进先出 (LIFO) 的方式添加新的期望。这意味着最新创建的期望将首先匹配(并执行)。
因此,要创建 GoogleMock 期望,使其在每次函数调用时都会 return 下一个数字,以下代码应该有效:
void testFunc()
{
for (std::size_t i = 9; i >= 0; i++)
EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i)).RetiresOnSaturation();
}
当然,在测试代码中调用模拟函数之前应该设置预期,因为否则Google模拟将不知道你打算做这样的事情.