简体   繁体   English

Qt测试模拟动态链接库

[英]Qt test mock dynamic linked library

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; “ app”正在使用一个库; the library is tested within the test_lib project. 该库在test_lib项目中进行了测试。

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!). 现在,我想测试该应用程序,但是我不想再次测试整个lib的东西(这是愚蠢的,可以不费吹灰之力!)。 So I need some way to mock away the whole lib. 因此,我需要某种方法来模拟整个lib。 Have anyone done this before in Qt and can help me out? 有人在Qt之前做过此事,可以帮助我吗? Is this possible within the Qt test framework? Qt测试框架中可能吗? I read already a lot of articles and SO questions, but I didn't find any solution for this special problem. 我已经阅读了很多文章和关于SO的问题,但是对于这个特殊问题,我没有找到任何解决方案。

I use Qt Creator 4.0.3 based on Qt 5.6.1, qmake with mscv2013 and the included Qt test framework. 我使用基于Qt 5.6.1的Qt Creator 4.0.3,带有mscv2013的qmake和随附的Qt测试框架。

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. 正如我在评论中建议的那样,创建一个仅模拟原始库的API的库,这是如何完成的。 Let's assume you have a class Foo with some trivial API in our original library: 假设您在原始库中有一个带有一些琐碎API的Foo类:

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. 要创建模拟库,您必须遵循与原始库相同的类层次结构,并保留公共API(可以忽略私有和受保护的东西),以便应用程序也可以针对该模拟库进行编译和链接。 So, our Foo class will look like: 因此,我们的Foo类将如下所示:

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: 在原始库中使用相同的示例Foo类:

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. 当您需要构建用于测试的应用程序时,只需使用定义的TEST_MODE预处理程序宏来构建库。 With this you will just bypass the unnecessary execution of library's code. 这样,您将绕过不必要的库代码执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM