Search code examples
c++unit-testingmockingstandard-librarystd

Mocking the C++ Standard Library


I'm unit testing a class in C++ and some of the public methods call private ones. I know convention is to test the public interface, but the classes' functionality depends on how these private methods in turn invoke other classes and their methods. This is similar to the public interface in the sense that no matter what happens to the private function it will still conform to the API.

I've been able to mock the classes invoked in the private function for the most part to test the API, but in a few cases I've run into places where the standard library is referenced and haven't managed to mock it. Are there any tricks to mocking standard library classes etc? Or should I skip them?

-- Also I'm not able to either change the source or use mocking libraries.


Solution

  • If you really wish to mock the standard library then the easiest (possibly only) approach is to instrument your code correctly. That is, instead of using the headers and std namespace directly you'll have to use an intermediary name.

    So invent a namespace, call it mstd. In your mocked mode this will be your mock namespace. In non-mock mode this will simply be an alias to std.

    For header files you'll have to avoid including the standard headers directly, but use a mocking layer. So instead of including <map> you could include <mk-map>. This header file will then decide between the standard library and your version. Perhaps like this:

    #ifdef MOCK_MODE
        #include "mock/map.hpp"
    #else
        #include <map>
    #endif
    

    You could alternately give a different include path to your compiler, one that comes before the standard libraries. However, since you have to alias the namespace anyway you'll still have to modify all of your code -- thus it's just as easy to include these special headers.

    This is about the only way I can see this working. Note that using LD_PRELOAD or any library technique will not work: the C++ standard library is made up of a lot of template classes and inline functions. You need to replace them right at compile time.