eranpeer / FakeIt

C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.
MIT License
1.24k stars 173 forks source link

Sequence verification with multiple mocks does not fail if some other function is in between #251

Open poeschlr opened 3 years ago

poeschlr commented 3 years ago

Hi,

The example from the quistart for sequence verification does imply that the "+" operator would match an exact sequence. If all called functions are from the same mock then it detects if there is a function between the two mocked functions i have around the "+" operator but if these 3 functions are from different mocks then it does not seem to detect this.


Common part of example:

struct SomeInterface {
   virtual void foo(void) = 0;
   virtual void foo1(void) = 0;
   virtual void foo2(void) = 0;
};

Mock<SomeInterface> mock;
Mock<SomeInterface> mock1;
Mock<SomeInterface> mock2;

void foo(void)
{
    mock.get().foo();
}

void foo1(void)
{
    mock.get().foo1();
}

void foo2(void)
{
    mock.get().foo2();
}

void fooM1(void)
{
    mock1.get().foo();
}

void fooM2(void)
{
    mock2.get().foo();
}

The working example (fails as expected)

void testFunction(void)
{
    foo();
    foo1();
    foo2();
}
SCENARIO("test")
{
    mock.Reset();

    GIVEN("the mocks")
    {
        Fake(Method(mock, foo));
        Fake(Method(mock, foo1));
        Fake(Method(mock, foo2));
        WHEN("called")
        {
           testFunction();
           THEN("verify")
           {
                 Verify(Method(mock, foo) + Method(mock, foo2));
           }
        }
    }
}

The non working example (does not fail as would be expected)

void testFunction2(void)
{
    foo();
    fooM1();
    fooM2();
}
SCENARIO("test2")
{
    mock.Reset();
    mock1.Reset();
    mock2.Reset();

    GIVEN("the mocks")
    {
        Fake(Method(mock, foo));
        Fake(Method(mock1, foo));
        Fake(Method(mock2, foo));
        WHEN("called")
        {
           testFunction2();
           THEN("verify")
           {
                 Verify(Method(mock, foo) + Method(mock2, foo));
           }
        }
    }
}

We use the single header file for catch2. And to be sure it is not already fixed downloaded (and integrated) the version of today (Relevant info from header: Generated: 2021-05-12 13:47:04.979584 -- And yes this version seems to have an issue with fail but i will make a separate issue there). We compile with MSVC-2019.

FranckRJ commented 3 years ago

It only check for mocks that are in the sequence.

Verify(Method(mock, foo) + Method(mock2, foo)); will only check that there is no other call from mock or mock2 between these two calls, but not from mock1 because it doesn't appear in the sequence verified.

FranckRJ commented 1 year ago

You can use Verification Scoping if you want to set a custom list of mocks that will be considered in the verification process, instead of relying on the automic list that only contains mocks that are directly referenced: https://github.com/eranpeer/FakeIt/wiki/Quickstart#verification-scoping

In your example, it would look like this:

Using(mock, mock1, mock2).Verify(Method(mock, foo) + Method(mock2, foo));