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

3

There are 3 best solutions below

0
On

Interaction between NeverCall and ExpectCall was not really thought through before - I never expected people to use NeverCall much at all, so I hadn't realized the interplay.

In the current released version a NeverCall would get an autoexpect on the previous ExpectCall, and all NeverCalls would be checked first. This results in ExpectCall/NeverCall to work as expected - ie, you first get the expect and then the NeverCall is active. In case of NeverCall/ExpectCall no autoexpects are added and the NeverCall gets priority. This is counter-intuitive and I think it's better to swap the behaviour so that ExpectCalls always get priority if they can match.

I've added your example as a new test case & swapped the match order of NeverCall and ExpectCall. I also removed the autoExpect for NeverCalls - 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, autoExpect on or off. Your second example would also work if the someCall is after the NeverCall is 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 .

4
On

You can't do that, because NeverCall is designed to throw an exception for the assertion. Seems completely illogical for me.

If you really want to get around that, setup the following

mocks.OnCallFunc(someFunc).Do(someFuncCalledHandler);

In your own handler you can implement the needed logic:

bool callAllowed = true; //global variable
void someFuncCalledHandler()
{
    if (!callAllowed)
    {
        throw MyNeverCallException();
    }
}

In your test, you can steer the behaviour of someFuncCalledHandler():

callAllowed = false;
someFunc();

By the way: It's a bad idea to mix up arrangement and action code in a test, as you've done in your sample code

3
On

The Hippomocks expectations are checked either when the MockRepository's destructor is called or when its VerifyAll() method is explicitly called. Call VerifyAll() before line 33 and your first example shall work fine.

I second the previous answer that the testing code and the tested code shouldn't be mixed up but I can imagine that it's only for the sake of a compact question.