如何存根/模拟Qt类?

时间:2011-04-08 10:10:02

标签: c++ unit-testing qt tdd 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;
    }
};

我想以这种方式进行测试(我使用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);
}

1 个答案:

答案 0 :(得分:3)

我认为你是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
  }
};