0

I created a test case with Catch2 and I am trying to use TrompeLoeil for finer testing. However the mock calls either don't happen at all, or happen but don't seem to be detecting by the framework.

Here is a minimal reproductible example :

class MyRealClass
{
public:
    virtual int returnSumOfValues(int a, int b)
    {
        return a + b;
    }
};

class MyMockClass : public MyRealClass
{
public:

    MAKE_MOCK2(returnSumOfValues, int(int,int));
};

class MyTestedClass
{
public:
    MyTestedClass(MyRealClass* _computeObj)
        : computeObj(_computeObj)
    {
    }

    int compute()
    {
        return computeObj->returnSumOfValues(2,3);
    }

    MyRealClass* computeObj;
};

TEST_CASE("Testing Trompe L'oeil")
{
    auto mock = new MyMockClass();
    MyTestedClass testedClass(mock);

    int val = testedClass.compute();

    CHECK(val == 5);
    REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);
}

And here is the error I get from running this test :

------------------------------------------------------------------------------- Testing Trompe L'oeil ------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164 ...............................................................................

../../../src/MEGAAutoTests/UnitTests/main.cpp:38: FAILED: explicitly with message: No match for call of returnSumOfValues with signature int(int,int) with. param _1 == 2 param _2 == 3

I debugged this step by step and the mocked returnSumOfValues() is the one being executed.

However, if I make MyRealClass::returnSumOfValues() not virtual, the mock class is not used at all.

And the error is :

------------------------------------------------------------------------------- Testing Trompe L'oeil ------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164 ...............................................................................

../../../src/MEGAAutoTests/UnitTests/main.cpp:43: FAILED: CHECK( failure.empty() ) with expansion: false with message: failure := "../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.
cpp:172 Unfulfilled expectation: Expected *mock.returnSumOfValues(2,3) to be called once, actually never called param _1 == 2 param _2 == 3 "

This seems to not be consistent with the official documentation, which states that :

The line MAKE_MOCK2(log, void(int severity, const std::string& msg)) creates a mock function void Logger::log(int, const std::string&). If MAKE_MOCKn(...) or MAKE_CONST_MOCKn(...) are used to implement a virtual function from a base class, it is always recommended to add a third macro parameter override since it gives the compiler an ability to complain about mistakes.

Recommended, not required. And to give the compiler more information, not to make the test work.

TL, DR

  1. Why is my code sample not working?
  2. Why do I need to make mocked functions virtual when the documentation suggests it is not mandatory?
Mickaël C. Guimarães
  • 1,020
  • 2
  • 14
  • 32

1 Answers1

0

The issue was that expectations need to be set beforehand.

I though they worked like assertions, checking a state after the code was executed, but this is not the case.

In this case, moving the call solved the problem. Here is the fixed code sample :

TEST_CASE("Testing Trompe L'oeil")
{
    auto mock = new MyMockClass();
    MyTestedClass testedClass(mock);
    REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);

    int val = testedClass.compute();

    CHECK(val == 5);
}

This is the solution to the first problem, the second one (only virtual functions can be mocked) remains unanswered.

Mickaël C. Guimarães
  • 1,020
  • 2
  • 14
  • 32