【问题标题】:Qt test mock dynamic linked libraryQt 测试模拟动态链接库
【发布时间】:2018-01-09 08:34:03
【问题描述】:

我有点困惑如何使用模拟和动态链接库。让我们假设一个项目结构如下

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)

“应用”正在使用库;该库在 test_lib 项目中进行了测试。

现在我想测试应用程序,但我不想再次测试整个 lib 的东西(这是愚蠢的,而且不费吹灰之力地加倍工作!)。所以我需要一些方法来模拟整个库。有没有人以前在 Qt 中做过这个并且可以帮助我?这可能在 Qt 测试框架内吗?我已经阅读了很多文章和 SO 问题,但我没有找到任何解决这个特殊问题的方法。

我使用基于 Qt 5.6.1 的 Qt Creator 4.0.3、带有 mscv2013 的 qmake 和包含的 Qt 测试框架。

【问题讨论】:

  • 你的问题我不清楚。您的测试应该定义他们正在测试的内容。如果您只想测试您的应用程序,请调用特定于该应用程序的函数,即使还加载了依赖库。
  • 希望我能让它更清楚一点……让我们假设 lib 有一些 bool init() 函数。此函数将调用应用程序的构造函数。 init() 函数做了很多已经在 test_lib 中测试过的东西。我不想在应用程序测试中间接进行测试(通过调用构造函数),我只想模拟该函数并返回 true。希望你明白我的意思……
  • 现在我明白了,谢谢。您可以使用存根而不是原始库的公共 API 创建一个模拟库,或者,如果您在“测试”模式下运行(使用预处理器宏),则在您的应用程序中根本不调用 init() 和其他库函数。
  • 没问题。模拟库正是我的想法,但我不知道如何制作它。你有任何链接/文章/动手吗?或者你能解释一下如何创建这个模拟库吗?如果你把这些东西放在一个答案中,我会接受它。

标签: c++ qt unit-testing mocking qttest


【解决方案1】:

正如我在 cmets 中提出的创建一个仅模拟原始库的 API 的库,这里是如何完成的。假设您在我们的原始库中有一个类 Foo 和一些简单的 API:

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

要创建模拟库,您必须遵循与保留公共 API 的原始库相同的类层次结构(可以忽略私有和受保护的内容),以便应用程序也可以编译和链接模拟库。因此,我们的 Foo 类将如下所示:

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

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

您必须对应用程序使用的所有类执行相同的技巧。 如果您想构建您的应用程序进行测试,您必须将其链接到模拟库而不是原始库。您不需要更改应用程序的代码,但它会调用不会执行任何操作的函数。

注意:这种方法可能并不总是正常工作,因为您的应用程序行为可能取决于库函数的执行方式和执行方式。

更新

另一种方法是保留单个库,但是使每个公共函数的内容有条件地构建。在原始库中使用相同的示例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();
};

当您需要构建应用程序进行测试时,只需使用定义的 TEST_MODE 预处理器宏构建库即可。这样您就可以绕过库代码的不必要执行。

【讨论】:

  • 感谢您的回答,但我有点困惑,或者答案对我来说不够清楚。如果我理解正确,我需要创建一个自己的 mock_lib 项目来生成一个模拟 dll 文件?该项目必须包含所有带有存根的导出函数(与原始 API 相同)。如果我构建“应用程序”进行测试,必须有某种机制来创建模拟 dll 而不是原始 dll?
  • 你正确地理解了我。我提出了一种替代解决方案,它不需要创建两个库,而是将其保存在一个库中。请查看我的更新。
猜你喜欢
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
相关资源
最近更新 更多