Как заглушки / макеты классов Qt? - PullRequest
5 голосов
/ 08 апреля 2011

Я новичок в тестировании и 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;
    }
};

И я хочу проверить это таким образом (я использовал синтаксис Гиппомокса, просто чтобы дать представление)

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 Ответ

3 голосов
/ 08 апреля 2011

Я думаю, что вы тестируете модули QSettings, но это не точка модульного тестирования.

Если вы хотите изучить TDD, начните с чего-то более простого.Например, попробуйте создать триаду классов MVP (модель и презентатор должны иметь интерфейсы, а view - это тип класса 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
  }
};
...