Imagine we have a unit test that first executes a sequence of code for which we expect a function someFunc not to be called, then executes a sequence of code for which we expect that function to be called exactly once. Using HippoMocks, we could write it like this:
#include <hippomocks.h>
void someFunc (void)
{
}
int main (int argc, char ** argv)
{
MockRepository mocks;
mocks.autoExpect = false;
mocks.NeverCallFunc(someFunc); // line 27
/* some testing code ... */
/* ... in the course of which someFunc does not get called ... */
mocks.ExpectCallFunc(someFunc); // line 33
/* other testing code ... */
someFunc();
/* ... in the course of which someFunc got called */
return 0;
}
However, when running the above snippet on Windows (compiled with Cygwin toolchain), a HippoMocks::ExpectationException is thrown:
terminate called after throwing an instance of 'HippoMocks::ExpectationException'
what(): Function someFunc() called with mismatching expectation!
Expectations set:
../main.cpp(33) Expectation for someFunc() on the mock at 0x0 was not satisfied.
Functions explicitly expected to not be called:
../main.cpp(27) Result set for someFunc() on the mock at 0x0 was used.
So I am wondering...
... (1), if HippoMocks is not designed to handle such a scenario. Does expecting that someFunc gets called (line 33) not replace the previous expectation in the corresponding mock respository?
... (2), why the second expectation (line 33) was not satified, as someFunc explicitely gets called. If any, I would have expected the first expectation (line 27) to not having been met?
Interestingly, things work the other way round. The following snippet runs without any issues:
#include <hippomocks.h>
void someFunc (void)
{
}
int main (int argc, char ** argv)
{
MockRepository mocks;
mocks.autoExpect = false;
mocks.ExpectCallFunc(someFunc); // line 27
/* some testing code ... */
someFunc();
/* ... in the course of which someFunc got called */
mocks.NeverCallFunc(someFunc); // line 33
/* other testing code ... */
/* ... in the course of which someFunc does not get called ... */
/* someFunc(); */
return 0;
}
Moreover, if a call to someFunc is inserted behind the second expectation in the second snippet (as indicated in the comment), this is detected and reported as violation to the "never call" expectation by HippoMocks as one would expect:
terminate called after throwing an instance of 'HippoMocks::ExpectationException'
what(): Function someFunc() called with mismatching expectation!
Expectations set:
../main.cpp(27) Expectation for someFunc() on the mock at 0x0 was satisfied.
Functions explicitly expected to not be called:
../main.cpp(33) Result set for someFunc() on the mock at 0x0 was used.
Any help of a HippoMocks expert would be appreciated...
Interaction between
NeverCallandExpectCallwas not really thought through before - I never expected people to useNeverCallmuch at all, so I hadn't realized the interplay.In the current released version a
NeverCallwould get an autoexpect on the previousExpectCall, and allNeverCalls would be checked first. This results inExpectCall/NeverCallto work as expected - ie, you first get the expect and then theNeverCallis active. In case ofNeverCall/ExpectCallnoautoexpects are added and theNeverCallgets priority. This is counter-intuitive and I think it's better to swap the behaviour so thatExpectCalls always get priority if they can match.I've added your example as a new test case & swapped the match order of
NeverCallandExpectCall. I also removed theautoExpectforNeverCalls - because that shouldn't have been there in the first place. The result is that both of your examples will now work in the way you expect them to,autoExpecton or off. Your second example would also work if thesomeCallis after theNeverCallis set up. This allows you to group your setup code more than before.If you want to test / switch to this version, note that it is still on the cpp11 branch. I will merge this to master & release when the branch is confirmed stable & the documentation properly expanded. There are no current known problems with it. It is on Github: https://github.com/dascandy/hippomocks/tree/cpp11 .