【问题标题】:Odd Behavior When Using ON_CALL before EXPECT_CALL with Gmock在 EXPECT_CALL 和 Gmock 之前使用 ON_CALL 时的奇怪行为
【发布时间】:2013-05-22 21:46:34
【问题描述】:

在使用 EXPECT_CALL 语句执行 ON_CALL 语句时,有没有人在 gmock 中看到过奇怪的行为?对我来说,以下代码中的 EXPECT_CALL 语句不起作用(它实际上并没有强制执行 Times 部分):

ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock")));
EXPECT_CALL(myMockObject, myMockMethod()).Times(99999);
myMockObject.myMockMethod();

我尝试过的其他解决方案:

从超类覆盖 myMockMethod 并让它简单地返回一个字符串文字。问题是我无法确定它后来被调用了多少次。

跳过 ON_CALL 部分以支持这样的事情:

EXPECT_CALL(myMockObject, myMockMethod())
    .Times(1)
    .WillRepeatedly(Return("hello mock"));

这会导致编译错误。

另外值得注意的是,我在此示例中使用的字符串文字实际上是自定义的,gmock 无法为其提供默认值(例如 bool)。

【问题讨论】:

  • .Times(1)你试过WillOnce(Return("hello mock"))吗?

标签: c++ unit-testing gmock


【解决方案1】:

您的原始代码中还有一些其他错误,您的问题中没有提到。如果您构建一个最小的自包含示例,则问题中提供的代码的行为符合您的预期。

例如下面的代码:

#include <string>
#include "gmock/gmock.h"

using ::testing::Return;

struct MyClass {
  virtual ~MyClass() {}
  virtual std::string myMockMethod() = 0;
};

struct MyMockClass : MyClass {
  MOCK_METHOD0(myMockMethod, std::string());
};

TEST(MyClass, Fails) {
  MyMockClass myMockObject;
  ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock"));
  EXPECT_CALL(myMockObject, myMockMethod()).Times(99999);
  myMockObject.myMockMethod();
}

TEST(MyClass, Passes) {
  MyMockClass myMockObject;
  EXPECT_CALL(myMockObject, myMockMethod()).Times(1).WillRepeatedly(Return("hello mock"));
  myMockObject.myMockMethod();
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

产生以下(预期的)输出:

[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[==========] 2 tests from MyClass
[ RUN      ] MyClass.Fails
..\src\main.cc(18): error: Actual function call count doesn't match EXPECT_CALL(myMockObject, myMockMethod())...
         Expected: to be called 99999 times
           Actual: called once - unsatisfied and active
[  FAILED  ] MyClass.Fails (0 ms)
[ RUN      ] MyClass.Passes
[       OK ] MyClass.Passes (0 ms)
[----------] 2 tests from MyClass (2 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (2 ms total)
[  PASSED  ] 1 test.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] MyClass.Fails

 1 FAILED TEST

如果您希望将模拟对象保存在测试夹具中,您可以这样做:

class MyClassTest : public testing::Test {
 protected:
  MyMockClass myMockObject_;
};

TEST_F(MyClassTest, Fails) {
  ON_CALL(myMockObject_, myMockMethod()).WillByDefault(Return("hello mock"));
  EXPECT_CALL(myMockObject_, myMockMethod()).Times(99999);
  myMockObject_.myMockMethod();
}

【讨论】:

  • 我的模拟对象是否需要在每个测试方法中实例化?我知道这是一种很好的形式(并且是独立的),但我通常会尝试在某种夹具中创建通用对象。
【解决方案2】:
 Mock::VerifyAndClearExpectations(&myMockObject);

这成功了。我仍然不确定如何在幕后管理期望,但这让我开始工作。

不过,我们将不胜感激任何进一步的解释。

【讨论】:

    猜你喜欢
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    • 2016-04-25
    • 2010-09-30
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多