GoogleMock:如何准确地期待一个带有特定参数的调用,并查看失败的诊断?
Posted
技术标签:
【中文标题】GoogleMock:如何准确地期待一个带有特定参数的调用,并查看失败的诊断?【英文标题】:GoogleMock: how to expect precisely one call with a certain argument, and see diagnostic on failure? 【发布时间】:2014-09-26 13:31:37 【问题描述】:也许是一个技巧问题,我的问题是,如果我写:
EXPECT_CALL(mock, handleMessage(_)).Times(0); // expectation #1
EXPECT_CALL(mock, handleMessage(Pointee(IsLike(aSpecificMessage)))); // expectation #2
... 和方法 handleMessage
被调用一次,但使用不同的参数(不是 aSpecificMessage
),那么失败看起来像:
Mock function called more times than expected - returning default value.
Function call: handleMessage(0x8b5378)
Returns: false
Expected: to be never called
Actual: called once - over-saturated and active
Google Mock 不会打印关于为什么参数与预期 #2 中的谓词不匹配的诊断信息。 这大概是因为期望 #1 是第一个失败的(?)。
如果我省略了期望 #1,那么失败就很冗长,大致如下:
Google Mock tried the following 1 expectation, but it didn't match:
../../test/Test.cpp:143: EXPECT_CALL(mock, handleMessage(Pointee(IsLike(aSpecificMessage))))...
Expected arg #0: points to a value that <....>
Actual: 0xfeaf18, which points to <.....>
我正在使用自定义匹配器IsLike
,并且遇到了生成非常明确的不匹配原因的麻烦,我希望将它们打印出来。我也不想放弃期望 #1,因为它位于“默认”部分,默认情况下,我不希望在其余测试中调用该模拟。
【问题讨论】:
【参考方案1】:看来您应该使用the StrictMock
template modifier。让我们使用这个简单的类和模拟:
struct Foo
virtual void function(int)
;
struct MockFoo: public Foo
MOCK_METHOD1(function, void(int x));
;
让我们从一个练习该方法的基本测试开始:
TEST(MockTest, basic_one_expectation)
MockFoo foo;
EXPECT_CALL(foo, function(4));
Foo& foo1(foo);
foo1.function(3);
输出:
[运行]模拟测试.basic_one_expectation 未知文件:失败 意外的模拟函数调用 - 直接返回。 函数调用:函数(3) Google Mock 尝试了以下 1 个期望,但不匹配: mock-test.cpp:298: EXPECT_CALL(foo, function(4))... 预期参数 #0:等于 4 实际:3 预期:被调用一次 实际:从未打电话 - 不满意和积极 mock-test.cpp:298:失败 实际函数调用计数与 EXPECT_CALL(foo, function(4)) 不匹配... 预期:被调用一次 实际:从未打电话 - 不满意和积极 [失败] MockTest.basic_one_expectation (1 ms)这是您已经考虑过的替代方案之一,但您不想要它,因为您有其他测试对是否调用该函数没有任何特别的期望,并且您希望这些测试失败,如果无论如何都会调用函数。提醒一下,让我们看看当我们尝试这样的测试时发生了什么:
TEST(MockTest, basic_no_expectation)
MockFoo foo;
Foo& foo1(foo);
foo1.function(3);
输出:
[运行]模拟测试.basic_no_expectation GMOCK 警告: 无趣的模拟函数调用 - 直接返回。 函数调用:函数(3) 堆栈跟踪: [确定] MockTest.basic_no_expectation (1 ms)我们收到警告,但测试仍然通过。这对你没有好处。看看StrictMock
有什么效果:
TEST(MockTest, strict_no_expectation)
::testing::StrictMock<MockFoo> foo;
Foo& foo1(foo);
foo1.function(3);
输出:
[运行] MockTest.strict_no_expectation 未知文件:失败 无趣的模拟函数调用 - 直接返回。 函数调用:函数(3) [失败] MockTest.strict_no_expectation (0 ms)我们不必明确表示我们不希望调用该函数,但是无论如何调用该函数时,测试都会正确失败。正是你想要的。
最后,让我们看看StrictMock
在函数参数有明确期望的情况下会发生什么:
TEST(MockTest, strict_one_expectation)
::testing::StrictMock<MockFoo> foo;
EXPECT_CALL(foo, function(4));
Foo& foo1(foo);
foo1.function(3);
输出:
[运行] MockTest.strict_one_expectation 未知文件:失败 意外的模拟函数调用 - 直接返回。 函数调用:函数(3) Google Mock 尝试了以下 1 个期望,但不匹配: mock-test.cpp:307: EXPECT_CALL(foo, function(4))... 预期参数 #0:等于 4 实际:3 预期:被调用一次 实际:从未打电话 - 不满意和积极 mock-test.cpp:307:失败 实际函数调用计数与 EXPECT_CALL(foo, function(4)) 不匹配... 预期:被调用一次 实际:从未打电话 - 不满意和积极 [失败] MockTest.strict_one_expectation (0 ms)诊断显示参数不匹配的原因,就像上面显示的原始 basic_one_expectation
测试一样。
【讨论】:
以上是关于GoogleMock:如何准确地期待一个带有特定参数的调用,并查看失败的诊断?的主要内容,如果未能解决你的问题,请参考以下文章
如何检查 googlemock 中作为 void 指针传递的字符串参数