如何存根/模拟Qt类?

ash*_*agi 5 c++ tdd qt unit-testing mocking

我是测试和TDD的新手但是决定试一试并学习.目前我正在尝试开发一个类SettingsManager来处理我的应用程序的设置.它将存储应用程序的状态以及何时关闭.SettingsManager将使用QSettings保存状态(并在启动时读取).现在我想模拟QSettings所以我的测试不依赖于随机状态.但是,由于我需要的方法(QSettings :: value())不是虚拟的,我找不到任何合理的方法来模拟/存根.

也许我在做一些概念错误的事情?或者有没有办法模拟非虚方法调用?

示例:假设我有这个类:

class SettingsManager
{    
private:
    /* app state variables */
    QSettings *settings;
    bool m_objectsVisible;

public:

    SettingsManager(QSettings *settings)
    {
       this->settings = settings;
    }

    void readSettings()
    {
       m_objectsVisible = settings.value("Settings/ObjectsVisible").toBool();
    }

    bool objectsVisible()
    {
       return m_objectsVisible;
    }
};
Run Code Online (Sandbox Code Playgroud)

我想以这种方式测试它(我使用Hippomocks语法只是为了给出一个想法)

void TestObjectsAreVisible() {
    MockRepository mocks;
    QSettings *settingsMock = mocks.ClassMock<QSettings>();
    mocks.ExpectCall(settingsMock , QSettings::value).With("Settings/ObjectsVisible").Return(true);
    SettingsManager *sManager = new SettingsManager(settingsMock);
    sManager->readSettings();
    assertTrue(sManager->objectsVisible);
}
Run Code Online (Sandbox Code Playgroud)

BЈо*_*вић 2

我认为您正在对 QSettings 进行单元测试,但这不是单元测试的重点。

如果你想学习 TDD,请从更简单的事情开始。例如,尝试创建一个 MVP 三元组(模型和演示者应该有接口,而视图是 qt 类类型)。然后对模型和演示者进行充分的单元测试。该视图不应该有任何逻辑——只有 qt 调用。

像这样的东西:

struct View : (some qt object )
{
  View( PresenterIface &p_ ) : p(p_) {}

  void buttonClicked()
  {
    p.buttonClicked();
  }

  PresenterIface p;
};

struct Presenter : PresenterIface
{
 Presenter( ModelIface &m_ ) : m(m){}
 void buttonClicked()
 {
  m.setValue();
 }

 ModelIface &m;
};

struct Model : ModelIface
{
  void setValue()
  {
    // do something
  }
};
Run Code Online (Sandbox Code Playgroud)

  • 借调了。不要测试 QSettings。测试保存应用程序设置的类。 (3认同)
  • 这个问题是完全正确的,而答案根本没有回答它。但是关于仅传递不同的 QSettings 对象的评论似乎是唯一的好主意。 (3认同)