Search code examples
c++qtmockingqnetworkaccessmanager

How to create a fake QNetworkAccessManager


Having a bit of a problem. I currently have a huge project that I want to test and most of if depends fully on how the QNetworkAccessManager actually responds to the calls. Since I can't really manually sit and pull out the ethernet cord just to get the result I want I would like to make a fake QNAM. Usally I would just dervie that same interface that a class dervies from and then just tell the object that is using it to have a baseclass pointer so that it can handle both the fake and the correct one without too much effort.

 InterfaceQNAM &_manager; // should have virtual put, post, finished() etc that both 
                         //  the real QNAM and the fake one would derive

However! Qt doesnt really do interface and the QNAM only inherits from QOobject and I really dont wanna be that loose with my code and just tell the class to do all the calls agains a QObject (which doesnt have a virtual put, post or anything). It would require too much code changes inside the class (casts, two different objects depending on which would we injected etc..etc.. ) How would I actaully solve this?

Had a look at the requested brach change QtMock but due to lack in documentation I havent been able to get it up and running.

Also, started to dervie from QNAM but since the methods that im using arent virtual it wouldnt pick mine up.

My class looks something like this:

class BaseRequest : public QObject {

    Q_OBJECT

protected:
    QNetworkAccessManager &_manager;
    QPointer<QNetworkReply> _reply; 
    QPointer<IParser> _parser; 


public:
    BaseRequest(QNetworkAccessManager &manager, IParser *parser = 0, QObject *parent = 0) 
        : QObject(parent), _manager(manager), _reply(0), _retryCount(0), _parser(parser) {}

    virtual ~BaseRequest(); 
}

It will then use the QNAM to do REST requests and check when it's finished.

So how would I be able to do a fake QNAM that I could insert into this code without having to change it too much? Is there any nice design patterns or anything that could solve this?


Solution

  • From the comments at the question, let me propose a detailed answer:

    class MyNAM : public QNetworkAccessManager
    {
      bool fakedNAM; // with setter and getter functions also...
      ...
      QNetworkReply *   post ( const QNetworkRequest & request, const QByteArray & data )
      ...
    }
    
    ...
    
    QNetworkReply *MyNAM::post ( const QNetworkRequest & request, const QByteArray & data ) 
    {
      if (fakedNAM) {
         // your debugging code
      }
      else {
         return QNetworkAccessManager::post(request, data);
      }
    }