Reputation: 404
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
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