0

I’m a little bit confused how to work with mock and dynamic linked libraries. Let’s assume a project structure like the following

subdirs.pro (subdir project)     
\- app (subdir project)
\-- app (executable, include and use lib)
\-- lib (dynamic library)
\- test (subdir project)
\-- test_app (test the app WITHOUT test lib again)
\-- test_lib (fully test of lib functions)

The ‘app’ is using a library; the library is tested within the test_lib project.

Now I want to test the app, but I don’t want to test the whole lib stuff again (which is stupid and double work with no effort!). So I need some way to mock away the whole lib. Have anyone done this before in Qt and can help me out? Is this possible within the Qt test framework? I read already a lot of articles and SO questions, but I didn’t find any solution for this special problem.

I use Qt Creator 4.0.3 based on Qt 5.6.1, qmake with mscv2013 and the included Qt test framework.

sandkasten
  • 603
  • 1
  • 8
  • 21
  • Your question is not clear to me. Your tests should define what they are testing. If you want to test your application only, call functions that specific to that very application, even if dependent library also loads. – vahancho Jan 09 '18 at 09:02
  • Hope I can make it a little bit clearer… Let’s assume the lib has some `bool init()` function. This function will call in the constructor of the app. The `init()` function do a whole lot of stuff which is already tested in `test_lib`. I don’t want to the test indirectly in the app test (with calling the constructor), I just want to mock the function away and return true. Hope you understand what I mean… – sandkasten Jan 09 '18 at 09:09
  • Now I see the point, thanks. You might create a mock library with stubs instead of public API of your original library, or, alternatively, in your application simply do not call `init()` and other library functions if you run in "test" mode (use preprocessor macros). – vahancho Jan 09 '18 at 09:45
  • No problem. The mock library is exactly what I’m thinking of, but I don’t have a clue how to make this. Have you any links/articles/hands on? Or can you explain it how to create this mock library? If you put these things into an answer, I will accept it. – sandkasten Jan 09 '18 at 10:01

1 Answers1

0

As I proposed in comments to create a library that will just mock the API of the original library, here is how it can be done. Let's assume you have a class Foo with some trivial API in our original library:

class Foo
{
public:
    void doSomething();
    int returnSomething();
private:
    void doSometingElse();
};

To create a mock library you have to follow the same class hierarchy as in the original library preserving the public API (private and protected stuff can be ignored), so that the application can compile and link against the mock library too. So, our Foo class will look like:

class Foo
{
public:
    // This is just a stub
    void doSomething()
    {
        // Do nothing
    }

    // This is just a stub
    int returnSomething()
    {
        return 0; // Some value
    }
};

You will have to do the same trick with all classes that your application uses. If you want to build your application for testing you have to link it rather against the mock library than the original one. You will not need to change the application's code, but it will call functions that will not do anything.

NOTE: This approach may not always work properly, because your application behavior may depend on how and what library functions do things.

UPDATE

Another approach is preserving single library, however make content of each public function to be build conditionally. With the same sample Foo class in the original library:

class Foo
{
public:
    void doSomething()
    {
    #ifdef TEST_MODE
        // Do nothing
    #else
        // Do things normally
    #endif
    }

    int returnSomething()
    {
    #ifdef TEST_MODE
        // Return some dummy value
    #else
        // Do the real calculations
    #endif
    }
private:
    void doSometingElse();
};

When you need to build your application for testing, just build the library with defined TEST_MODE preprocessor macro. With this you will just bypass the unnecessary execution of library's code.

vahancho
  • 20,808
  • 3
  • 47
  • 55
  • Thanks for the answer, but I’m a little bit confused or maybe the answer is not clear enough to me. If I understand you right, I need to create an own mock_lib project which generates a mock dll file? This project must include all exported functions (same as the original API) with stubs. If I build ‘app’ for testing, there must be some mechanism to create the mocked dll instead of the original dll? – sandkasten Jan 09 '18 at 10:54
  • You understood me correctly. I came up with an alternative solution that doesn't require creation of two libraries, but keep it in a single one. Please see my update. – vahancho Jan 09 '18 at 11:28