Is there a way to make mock functions "interesting" with ON_CALL?

Bulletmagnet picture Bulletmagnet · Oct 2, 2014 · Viewed 16.9k times · Source

Given:

#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();
}

The output is:

$ ./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

In both cases, Gmock behaves correctly w.r.t. applying the behavior (or not, in TC33). But why does it say "Uninteresting mock function call" in both cases? Are mock function calls interesting only when specified with EXPECT_CALL ?

Answer

πάντα ῥεῖ picture πάντα ῥεῖ · Oct 2, 2014

"Are mock function calls interesting only when specified with EXPECT_CALL ?"

In short, yes.
The ON_CALL() macro only influences the action to be taken on a mock method call, but not the call expectations set on the mock object.

You can use the NiceMock<> template though, to suppress these warnings in general.
To cite from google mocks "Cookbook"

Suppose your test uses a mock class MockFoo:

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

If a method of mock_foo other than DoThis() is called, it will be reported by Google Mock as a warning. However, if you rewrite your test to use NiceMock instead, the warning will be gone, resulting in a cleaner test output:

using ::testing::NiceMock;

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

NiceMock<MockFoo> is a subclass of MockFoo, so it can be used wherever MockFoo is accepted.