chikuba
chikuba

Reputation: 4357

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?

Upvotes: 2

Views: 1398

Answers (2)

felixgaal
felixgaal

Reputation: 2423

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

Upvotes: 2

Edward Strange
Edward Strange

Reputation: 40887

I was going to suggest that you make your class a template and then you can override that way...but of course since you're implementing a Q_OBJECT you cannot. No preprocessor stuff will work either.

You'll have to use multiple layers of abstraction here. A base class that implements the non-signal stuff in your Q_OBJECT and a base class that provides the minimal interface you need to use within the QNetworkAccess thingy. Then you can make whatever you need virtual and you can make a test version and a Qt version of either/or/both.

You might be able to get away without having to implement a base for your Q_OBJECT if you make the QNetwork thingy base you create convert Qt signals into something compatible with C++ such as boost::signals.

Good luck. Trying to get Qt to do what you expect to be able to do in C++ is a hair losing experience.

Upvotes: 0

Related Questions