Gmock only expect a specific call - c++

I have a C++ class I am attempting to test with GMock. I have the following mock class:
class MyTestMock
{
public:
MOCK_METHOD1(myCoolMethod, int(const char*));
MOCK_METHOD1(myCoolMethod, int(string));
}
Then in my test the following happens:
MyTestMock myMock;
if ( myMock.myCoolMethod("stuff") )
{
// Stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("moarStuff") )
{
// More stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("foo") )
{
// This I care about and want to execute
}
What I would like to do is allow the first two calls to be uninteresting calls that return the default for integers, 0, while I set up a specific expectation on the third call to return 1. This was my attempt to do so:
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
However, this ends up making the test fail. If I do this instead:
EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
my test passes fine. I am attempting to make unit testing as painless as possible on an old, massive, monolithic-style codebase, so I'd really like to not need the extra magic line to tell it to return the default value. Any ideas on how I can do this with just the one expectation without tanking my test?

I guess my answer is not very "expected" for testing "an old, massive, monolithic-style codebase" with possible huge numbers of such CoolMethods..., but, unfortunately this is how google-mock works. As you can read in their FAQ:
Having an ON_CALL in the set-up part of a test doesn't mean that the
calls are expected. If there's no EXPECT_CALL and the method is
called, it's possibly an error. If we quietly let the call go through
without notifying the user, bugs may creep in unnoticed.
The same is with "default" ON_CALL - I mean when you did not write explicitly ON_CALL because default value for a type (in your case 0 for int) is perfectly OK.
My advice is to always put such general expectation in SetUp function of your test suite - this way your test cases are not overloaded with many magic expectations:
class MyTestSuite : public ::testing::Test
{
protected:
MyTestMock myMock;
void SetUp() override
{
EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
}
};
This way you have "annoying" lines only in one place, and your test cases are "clear":
TEST_F(MyTestSuite, shallDoSomethingWhenCoolMethodAcceptsFoo)
{
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
}
TEST_F(MyTestSuite, shallDoSomethingElseWhenCoolMethodAcceptsMoarStuff)
{
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("moarStuff"))).WillOnce(Return(1));
}

Related

Google Test Expect Call from a Function

Say I have a simple test with mocks.
#include "boost/interprocess/detail/interprocess_tester.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace ::testing;
struct IInterface
{
virtual void method(int foo) = 0;
};
struct SimpleMock : public IInterface
{
MOCK_METHOD1(method, void(int foo));
};
struct TestFixture : public Test
{
TestFixture()
{
// Don't care about other invocations not expected
EXPECT_CALL(mock, method(_)).Times(AnyNumber());
}
void setupExpectation(int data)
{
EXPECT_CALL(mock, method(data)).Times(1);
}
SimpleMock mock;
};
TEST_F(TestFixture, SimpleTest)
{
setupExpectation(2);
mock.method(2);
setupExpectation(5);
mock.method(3); // will fail expectation
}
This will fail with the message below referencing into the helper method, which makes it hard to debug or figure which expectation failed since I don't see the line I called setupExpectation or the actual argument value.
test_HarmonicTherapyStateMachineAit.cpp:27: Failure
Actual function call count doesn't match EXPECT_CALL(mock, method(data))...
Expected: to be called once
Actual: never called - unsatisfied and active
Note my actual use case has more complicated expect calls where I think it warrants splitting it into a separate method (and having multiple expectations in one test). However, I'm not sure how to get a more informative error message from this.
I've read about http://google.github.io/googletest/gmock_cook_book.html#controlling-how-much-information-gmock-prints. However, this provides more information than I really want, which is just a line number of the function that calls setupExpectation.
I also just tried making a MACRO to wrap the common expectations. This would be easy in this simple case. However, my actual use case has more complicated logic that I'd rather not place into a macro.
Even if I could do something like EXPECT_CALL(...).Times(1) << "argument: " << foo; That would be helpful.
Any help would be appreciated.
Currently I had the same problem, that gmock provides me very few information. My solution was to write a custom Matcher.
The syntax of the EXPECT_CALL macro is according to the documentation:
EXPECT_CALL(mock_object, method(matchers))
A quick solution could be to write a matcher, which in case of an error prints a message to the screen.
e.g:
MATCHER_P2(isEqual, expected, line, "")
{
bool isEqual = arg == expected;
if(!isEqual)
printf("Expected argument: %d, actual: %d (EXPECT_CALL line: %d)\n", expected, arg, line);
return isEqual;
}
The EXPECT_CALL then changes to
EXPECT_CALL(mock, method(isEqual(3, __LINE__))).Times(1);
Please let me know if you have another/better solution to this.

EXPECT_CALL(mock, f(N)) vs f(K) followed by f(N)

I'm trying to understand how EXPECT_CALLs work and I'm stuck with a strange behavior (in my opinion strange). Let's say my code does this (let's assume there is a mock and f(int) is it's method, also let's assume that SomeNiceMock is a NiceMock):
void SomeMock::f(int) { ... }
NiceMock<SomeMock> someNiceMock;
void runCycle(int n) { someNiceMock.f(n); }
Now if in test I will do the following
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(1);
runCycle(2);
::testing::Mock::VerifyAndClearExpectations(&mock);
I'm getting an error that f(int) was assumed to be called with 2 but was called with 1.
Expected: to be called at least once
Actual: never called - unsatisfied and active
If I do it like so:
runCycle(1);
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(2);
::testing::Mock::VerifyAndClearExpectations(&mock);
Everything works.
I can live with this behavior I just don't understand the reason behind it. someNiceMock is a NiceMock so it should not complain about f(int) being called with some other argument then expected as long as there was actually a call to f(int) with an expected argument. Second call runCycle(2) did call f(2). So why wasn't the call f(1) simply ignored and test failed? Is is so that if I specify an EXPECT_CALL even for a NiceMock if this call will be with a different argument (but later there will be another call with a proper argument) the test will fail? Isn't that counter-intuitive considering that this is a NiceMock and a call to f(2) actually happened in both cases?
EDIT: And how should I then test such behavior? Let's say I'm having some number generator and I want to test that when called 10 times it returns 5 at least 3 times (and I don't care about other results. I would expect to code it like so (sorry if I mess the syntax, I'm not that good at google mock):
struct INumberGeneratorSink {
virtual void consumeNumber(int number) = 0;
};
struct NumberGeneratorSink : public INumberGeneratorSink {
void consumeNumber(int number) override { ... }
};
struct NumberGeneratorSinkMock : public INumberGeneratorSink {
MOCK_METHOD1(consumeNumber, void(int number));
};
void numberGeneratorFunction(INumberGeneratorSink &sink)
{
for (int i = 0; i < 10; i++)
{
sink.consumeNumber(getNumberFromSomewhere());
}
}
NumberGeneratorSinkMock sinkMock;
NiceMock<NumberGeneratorSinkMock> niceSinkMock;
EXPECT_CALL(niceSinkMock, consumeNumber(5)).Times(AtLeast(3));
numberGeneratorFunction(niceSinkMock);
How am I suppose to code stuff like that? If there are some syntax error please correct me, but my question is more like - if I care only about that consumeNumber is called 3 times with value 5 and I don't care about the rest how can I code it? Do I have to write something like:
// not sure about syntax for Any(),
// maybe it doesn't exist and has to be AtLeast(1)
EXPECT_CALL(niceSinkMock, consumeNumber(_)).Times(Any());
EXPECT_CALL(niceSinkMock, consumeNumber(5)).Times(AtLeast(3));
Will that work? Won't first EXPECT_CALL just match everything and test will pass even if consumeNumber will never be called with 5 as argument?
I totally agree, gmock can be confusing concerning the expectations. ;-)
1) Why does the following fail?
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(1);
runCycle(2);
If a mock method has no EXPECT_CALL but is called, Google Mock will print a warning. To suppress this warning, you can use a NiceMock. However, if an EXPECT_CALL exists, it will and should fail.
2) Why does the following pass?
runCycle(1);
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(2);
Easy answer: The EXPECT_CALL has to be written before. But this way of writing tests should not be the usual way.
3) The Solution to handle multiple expectations
From the gmock cook book:
"By default, when a mock method is invoked, Google Mock will search the expectations in the reverse order they are defined, and stop when
an active expectation that matches the arguments is found"
Your last code snipped is almost right. The correct implementation of Times(Any()) is to omit it.
EXPECT_CALL(someNiceMock, f(_));
EXPECT_CALL(someNiceMock, f(2)).Times(1);
runCycle(1);
runCycle(2);
Also please notice, that your Mock "SomeMock" needs a "mocked" method.
E.g.:
class SomeMock {
public:
MOCK_CONST_METHOD1(f, void(int i));
};

Globally check value in mock

I have a mock that represents an API wrapper.
class MockApiWrapper : public ApiWrapper {
public:
MockNrfWrapper();
virtual ~MockNrfWrapper();
MOCK_METHOD1(api_do, void(int param));
};
Lets assume that api_do should never be called with param = 0. Since I use this mock "everywhere", I would like to append an assertion/expect to each call made to api_do. Example:
void MyClass::InvalidCallsToApi(void) {
// api->api_do(0); // Fails "global assert"
// api->api_do(1); // Fails by specific test
api->api_do(2); // Valid call
}
TEST(MyTestCase, FirstTest) {
// Mock always checks that api_do is not called
// with argument of 0
EXPECT_CALL(api, api_do(Ne(1));
uut->InvalidCallsToApi();
}
I tried doing this with an ON_CALL and Invoke in the constructor, but either it was overridden by the added EXPECT in the test, or I got compilation error (couldn't do ASSERT or EXPECT in invoked call).
I hope my problem statement is clear. Thanks in advance for any input!
I've came up with one solution, it's not the nicest, but acceptable IMO.
Code:
struct BInterface {
virtual void foo(int) = 0;
};
struct BMock : public BInterface {
MOCK_METHOD1(foo, void(int));
BMock() {
ON_CALL(*this, foo(0))
.WillByDefault(::testing::InvokeWithoutArgs([](){ADD_FAILURE() << "This function can't be called with argument 0";}));
}
};
void testedMethod(int a) {
BInterface* myB = new BMock;
myB->foo(a);
delete myB;
}
TEST(myTest, okCase) {
testedMethod(1);
}
TEST(myTest, notOkCase) {
testedMethod(0);
}
Explanation:
We add a default action to BMock, for every call of foo method with argument 0.
In this action, we call a lambda, which uses GTest macro ADD_FAILURE() to generate a non-fatal fail - equivalent of EXPECT_* macros. You can use FAIL() instead for a fatal failure like in ASSERT_* macros.
We use ON_CALL macro in mock's constructor, which allows to avoid calling it with every other mock object.
Limitations:
The same trick won't work with EXPECT_CALL for example - I don't know GMock implementaion, but I assume EXPECT_CALL requires a fully initialized object.
A call with matcher that accepts 0 will still pass (i.e. EXPECT_CALL(myB, foo(::testing::_));, but that's the case in every other GMock expectations. GMock will always shadow older expectations when newer ones are encountered. You have to create your expectations in such a way that they won't override the previous expectations.
Adding .RetiresOnSaturation() to all your EXPECT_CALL will make sure that calls are forwarded to default action (set by ON_CALL), when they are not interesting.
Custom matchers will be helpful in cases when there are multiple disallowed values.
MATCHER(IsValidApiArg, ""){return arg == 0 || arg == 1;}
ON_CALL(*this, api_foo(!IsValidApiArg)
.WillByDefault(::testing::InvokeWithoutArgs([](){ADD_FAILURE();}));
EXPECT_CALL(myMock, api_foo(IsValidApiArg));
Note: I still can't believe that GMock doesn't provide a default action for simply generating a failure. Perhaps you can find something better suitable deep in documentation.
You can also create a custom action for that, to avoid all that Invoke and lambdas.

how to verify a void method 'returned' in mockito

I am testing a function which is of below structure:
void method1() {
if(booleanCondition1) {
return;
}
callMethod2();
callMethod3();
...
..
callMethod-n();
}
I have to write a mock test for this, when booleanCondition1 evaluates to TRUE.
One way is make sure, callMethod2(), and callMethod3() and so on until callMethod-n() are never invoked(using Mockito.never()).
Is there any efficient way of doing this rather than making sure all the statements after return were not invoked?
In other words, can i verify if "return" statement was invoked using Mockito?
You can't test which return statement was encountered, but you can do verifyZeroInteractions or verifyNoMoreInteractions to encompass a lot of verify(mock, never()) assertions.
Use it sparingly--verifyNoMoreInteractions can lead to brittle tests if overused.

Google Mock Return a live element using ON_CALL

I read through Google Mock: Return() a list of values and found out how to return a single element from a vector on each EXPECT_CALL, as such I wrote the following code which works:
{
testing::InSequence s1;
for (auto anElem:myVecCollection) {
EXPECT_CALL(myMockInstance, execute())
.WillOnce(testing::Return(anElem));
}
}
so far so good...
Now I read not to use EXPECT_CALL unless you need to. https://groups.google.com/forum/#!topic/googlemock/pRyZwyWmrRE
My use case, myMockInstance is really a stub providing data to the SUT(software under test).
However, a simple EXPECT_CALL to ON_CALL replacement will not work(??), since ON_CALL with WillByDefault only calculates the return type only once(??)
As such I tried setting up an ACTION.
ACTION_P(IncrementAndReturnPointee, p)
{
return (p)++;
}
ON_CALL(myMockInstance, execute())
.WillByDefault(testing::Return
(*(IncrementAndReturnPointee(myVecCollection.cbegin()))));
Clang gives
error: expected expression 'ACTION_P(IncrementAndReturnPointee, p)'
Then I tried setting up a functor and use the Invoke method on it.
struct Funct
{
Funct() : i(0){}
myClass mockFunc(std::vector<myClass> &aVecOfMyclass)
{
return aVecOfMyclass[i++];
}
int i;
};
Funct functor;
ON_CALL(myMockInstance, execute())
.WillByDefault(testing::Return(testing::Invoke(&functor, functor.mockFunc(myVecCollection))));
Clang gives
no matching function for call to 'ImplicitCast_'
: value_(::testing::internal::ImplicitCast_<Result>(value)) {}
Now , I am fairly new to google-mock but have used google-test extensively.
I am a bit lost with the Google-Mock doc. I wanted to know, whether I am on the right path, in terms of what I needed.
If one of you could point to me , which approach is the correct one; or whether I am even close to the right approach, I can take it from there and debug the "close to right approach" further.
Thanks
testing::Return is an action. Your code should look like:
ACTION_P(IncrementAndReturnPointee, p)
{
return *(p++);
}
ON_CALL(myMockInstance, execute())
.WillByDefault(IncrementAndReturnPointee(myVecCollection.cbegin()));
As a side note, it doesn't look like a good idea to use a finite collection myVecCollection. You will probably get a more robust test if you figure out an implementation of the action that creates a new element to return on the fly.