Hi Martin,
Great question! Glad that you asked it. :)
There is one significant difference between the two constructs:
ON_CALL is orthogonal to EXPECT_CALLs; EXPECT_CALL().Times(AnyNumber())) is not orthogonal to other EXPECT_CALLs.
What do I mean?
Suppose you have a group of related tests that all make use of the same mock object but need to set different expectations on it. You don't want to repeatedly define what the mock should do when invoked (as it's largely the same for all your tests), so you define its default actions in your test fixture, and put different EXPECT_CALLs in different TEST_Fs:
class MyTest : public testing::Test {
protected:
MyTest() {
ON_CALL(mock_bar_, Foo(_)).WillByDefault(Return(42));
...
}
MockBar mock_bar_;
};
TEST_F(MyTest, Quarks) {
EXPECT_CALL(mock_bar_, Foo("a")).Times(2);
...
}
The test says that Foo() will be called twice, each time with argument "a". If Foo() is called with argument "b", for example, it will fail as there's no matching expectation.
Now consider the same test code, except that we write EXPECT_CALL().Times(AnyNumber()) instead of ON_CALL:
class MyTest : public testing::Test {
protected:
MyTest() {
EXPECT_CALL(mock_bar_, Foo(_))
.Times(AnyNumber())
.WillRepeatedly(Return(42));
...
}
MockBar mock_bar_;
};
TEST_F(MyTest, Quarks) {
EXPECT_CALL(mock_bar_, Foo("a")).Times(2);
...
}
The semantics of the test has changed. Now, if Foo() is called 3 times, with arguments "a", "a", and "b" respectively, the 3rd call will succeed, as it matches the "catch-all" EXPECT_CALL in the test fixture. This may not be what you want.
So here's the moral:
Use ON_CALL unless you intend to affect the expectation on the method.
What about the annoying warnings about "uninteresting calls", then? I agree that they are annoying when we don't really care about whether the method is called or not. That's why I recommend to use nice mocks (
https://code.google.com/p/googlemock/wiki/CookBook#Nice_Mocks_and_Strict_Mocks) by default (and only set expectations when we intend to verify the interaction). That is, instead of
MockFoo mock_foo_;
write
NiceMock<MockFoo> mock_foo_;