ashagi
ashagi

Reputation: 404

How to stub/mock Qt classes?

I am new to testing and TDD but decided to give it a try and learn. Currently I am trying to develop a class SettingsManager that would handle settings of my app. It would store app's state and when it closes SettingsManager will save the state using QSettings (and read when started). Now I want to mock QSettings so I my tests will not depend on random state. However, I could not find any sensible way of mocking/stubbing it because the method I need (QSettings::value()) is not virtual.

Perhaps I am doing something conceptually wrong? Or is there a way to mock that non-virtual method call?

Example: suppose I have this class:

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;
    }
};

And I want to test it that way (I used Hippomocks syntax just to give an idea)

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);
}

Upvotes: 10

Views: 6616

Answers (1)

BЈовић
BЈовић

Reputation: 64223

I think you are unit testing QSettings, but that is not a point of unit testing.

If you want to learn TDD, start with something simpler. For example, try to create a MVP triad of classes (model and presenter should have interfaces, while view is a qt class type). Then fully unit test model and presenter. The view should not have any logic - only qt calls.

Something like this :

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
  }
};

Upvotes: 2

Related Questions