【问题标题】:Is there a way to make mock functions "interesting" with ON_CALL?有没有办法用 ON_CALL 使模拟函数“有趣”?
【发布时间】:2014-11-27 05:01:31
【问题描述】:

给定:

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

using namespace testing; // tsk, tsk

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

struct Mockable {
    virtual std::string ify(int x) const;
};

std::string Mockable::ify(int x) const
{
    return std::to_string(x);
}

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

struct Mocked : public Mockable {
    MOCK_CONST_METHOD1(ify, std::string(int));
};

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

std::string tested(Mockable const& u, int x)
{
    return u.ify(x);
}

TEST(TC,T42)
{
    Mocked mock;
    ON_CALL(mock, ify(Eq(42)))
    .WillByDefault(Return("33"));

    std::string const& ret = tested(mock, 42);
    EXPECT_EQ("42", ret);
}

TEST(TC,T33)
{
    Mocked mock;
    ON_CALL(mock, ify(Eq(33)))
    .WillByDefault(Return("333"));

    std::string const& ret = tested(mock, 42);
    EXPECT_EQ("42", ret);
}

int main(int argc, char *argv[])
{
    ::testing::InitGoogleTest(&argc, argv);
    //::testing::FLAGS_gmock_verbose = "info";

    return RUN_ALL_TESTS();
}

输出是:

$ ./mocktest 
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from TC
[ RUN      ] TC.T42

GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
mocktest.cc:40:
    Function call: ify(42)
          Returns: "33"
Stack trace:
mocktest.cc:44: Failure
Value of: ret
  Actual: "33"
Expected: "42"
[  FAILED  ] TC.T42 (0 ms)
[ RUN      ] TC.T33

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: ify(42)
          Returns: ""
Stack trace:
mocktest.cc:54: Failure
Value of: ret
  Actual: ""
Expected: "42"
[  FAILED  ] TC.T33 (1 ms)
[----------] 2 tests from TC (1 ms total)

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

在这两种情况下,Gmock 的行为都是正确的。应用行为(或不应用,在 TC33 中)。但是为什么在这两种情况下都说“无趣的模拟函数调用”呢?模拟函数调用是否只有在使用 EXPECT_CALL 指定时才有意义?

【问题讨论】:

  • 使用 ::testing::nice_mock&lt;Mocked&gt; mock; 来避免这些警告,因为在模拟上没有明确预期的调用。
  • 噢!我只检查了 gmock 食谱和备忘单:(
  • @Bulletmagnet 这里有更多关于NiceMock&lt;&gt;的信息,抱歉有错别字。

标签: c++ unit-testing gmock


【解决方案1】:

“只有在使用 EXPECT_CALL 指定时,模拟函数调用才有意义吗?”

简而言之,是的。
ON_CALL() 宏仅影响要对模拟方法调用执行的操作,而不影响在模拟对象上设置的调用预期。

不过,您可以使用NiceMock&lt;&gt; 模板来抑制这些警告。
To cite from google mocks "Cookbook"

假设您的测试使用模拟类 MockFoo:

TEST(...) {
  MockFoo mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}

如果调用了 DoThis() 以外的 mock_foo 方法,Google Mock 将报告为警告。但是,如果您改写测试以使用 NiceMock,警告将会消失,从而产生更清晰的测试输出:

using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}

NiceMock&lt;MockFoo&gt;MockFoo 的子类,因此可以在任何接受MockFoo 的地方使用。

【讨论】:

    猜你喜欢
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 2022-07-25
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多