Search code examples
c++fakeit

Mocking an 3rd party library using fakeit


I am writing my own library/class that makes use of a 3rd party library. I want to write tests for my own class, and mock the 3rd party library. In one of the tests, I want to make sure that when a function on my class is being called, another function in the 3rd party library is also begin called as well. I though the FakeIt library would be a good idea to test this.

This is a sample of my testing code:

#include "MyTest.h"
#include "fakeit.hpp"

using namespace fakeit;

int main() {
    MyTest dt;
    Mock<ExternLib> mock;
    Fake(Method(mock, someFunc));
    ExternLib& el = mock.get();
    dt.begin();
    Verify(Method(mock, someFunc));
    return 0;
}

When this is run though, it throws a fakeit::SequenceVerificationException with

Expected pattern: mock.someFunc( Any arguments )
Expected matches: at least 1
Actual matches  : 0
Actual sequence : total of 0 actual invocations.

So clearly, the mock didn't work and it's method wasn't called. Any idea how I can mock this class and verify that its method is being called?

MyTest.cpp just is just a simple test and will be my full library/class:

#include "MyTest.h"

MyTest::MyTest() {
    _manager = new ExternLib();
}

void MyTest::begin() {
    result = _manager->someFunc();
}

and it's header file:

#pragma once
#include "Externlib.h"

class MyTest {
    public:
        MyTest();
        virtual void begin();
        int result = 3;
    private:
        ExternLib *_manager;
};

ExternLib is a mock version of the 3rd party library. My implementation implements the bare necessities of the real interface, and the functions don't actually do anything. The implementation is actually basically just there to satisfy the #include Externlib.h statements.

This is my Externlib.cpp:

#include "Externlib.h"

ExternLib:: ExternLib() {}

int ExternLib::someFunc() {
    return 5;
}

and the header file:

#pragma once

class ExternLib {
    public:
        ExternLib();
        virtual int someFunc();
};

Solution

  • To explain the fakeit::SequenceVerificationException: With the line Mock<ExternLib> mock; you create a new instance of ExternLib, which does never get called by MyTest (because MyTest creates it's own instance of ExternLib). To test invokation, you could either

    • expose the ExternLib instance stored in _manager to your test by making it public or add an accessor, and then spy on it (Mock<ExternLib> mock(MyTest._manager); or similar)
    • swap the ExternLib instance stored in MyTest::_manager with your ExternLib Mock instance.

    But this means exposing your Subject Under Test's inner workings for the sake of being testable, which may not be desired.