1

也许是一个技巧问题,我的问题是,如果我写:

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,因为它位于“默认”部分,默认情况下,我不希望在其余测试中调用该模拟。

4

1 回答 1

3

看起来你应该使用模板StrictMock修饰符。让我们使用这个简单的类和模拟:

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上面显示的原始测试一样。

于 2014-09-26T15:15:13.630 回答