Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using Qt Test and private members
Forum Updated to NodeBB v4.3 + New Features

Using Qt Test and private members

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AslundA Offline
    AslundA Offline
    Aslund
    wrote on last edited by
    #1

    Hello everyone

    For far too long I have been too lazy to properly using Qt Test in my development process and now I am starting to try to implement it. But I have hit a wall regarding private members.
    Let me illustrate with an example with a simple class I have made.

    class SqlComm : public QObject
    {
        Q_OBJECT
    public:
        SqlComm(QSqlDatabase _database, QObject* parent = nullptr);
    
        void setDatabase(const QString &&host, const QString &&database);
    
        void setUser(const QString &&user, const QString &&psswd);
    
        void connectToDB();
    
        unsigned int getNextDBSerial();
    
    protected:
        QSqlDatabase*    db;
        QSqlQuery*       query;
    };
    

    Since I am doing unit testing, my plan is to simplify the testing by making a QSqlDatabase stub, where I can return different results and answers to simulate actual response from the database. But the QSqlDatabase is a private member that I can not access to insert the stub.
    I have searched and found different answers:

    • Add a define changing private members into public (#define private public)

    • Do not use private members but use protected instead. Subclass my class and raise access level to public.

    • Use interface (I have not entirely understood this one yet)

    The two first options I feel is a bit dirty and third one seem overly complicated.

    How would you test this class?

    Regards
    Sebastian

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2
      1. Why do you even have QSqlDatabase as a member? The fact that it is a pointer worries me even more
      2. "Use interface" is one of the possible solutions, the other alternative is to move the private members into a pimpl and just have different versions of the private class for test and production (see https://wiki.qt.io/D-Pointer)
      3. The easiest and, if you ask me, more robust way to actually test it is to add a test db (a sqlite database file if you don't have a full fledged test db server) to your project and have the test program run off it rather than the production one. It's the only real way to actually test what will happen in production

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      AslundA 1 Reply Last reply
      5
      • VRoninV VRonin
        1. Why do you even have QSqlDatabase as a member? The fact that it is a pointer worries me even more
        2. "Use interface" is one of the possible solutions, the other alternative is to move the private members into a pimpl and just have different versions of the private class for test and production (see https://wiki.qt.io/D-Pointer)
        3. The easiest and, if you ask me, more robust way to actually test it is to add a test db (a sqlite database file if you don't have a full fledged test db server) to your project and have the test program run off it rather than the production one. It's the only real way to actually test what will happen in production
        AslundA Offline
        AslundA Offline
        Aslund
        wrote on last edited by
        #3

        Hey VRonin

        Thank you for your fast response and input.

        @VRonin said in Using Qt Test and private members:

        1. Why do you even have QSqlDatabase as a member? The fact that it is a pointer worries me even more

        What is wrong with this approach? Would it be better in your opinion to subclass QSqlDatabase?

        Regards
        Sebastian

        jsulmJ 1 Reply Last reply
        0
        • AslundA Aslund

          Hey VRonin

          Thank you for your fast response and input.

          @VRonin said in Using Qt Test and private members:

          1. Why do you even have QSqlDatabase as a member? The fact that it is a pointer worries me even more

          What is wrong with this approach? Would it be better in your opinion to subclass QSqlDatabase?

          Regards
          Sebastian

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Aslund said in Using Qt Test and private members:

          QSqlDatabase

          is a singleton and contains all databases you created. So, why do you need a pointer to a QSqlDatabase?
          See https://doc.qt.io/qt-5/qsqldatabase.html

          // Add database
          QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
          db.setHostName("acidalia");
          db.setDatabaseName("customdb");
          db.setUserName("mojito");
          db.setPassword("J0a1m8");
          bool ok = db.open();
          ...
          // Here you get your database
          QSqlDatabase db = QSqlDatabase::database();
          

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          AslundA 1 Reply Last reply
          5
          • jsulmJ jsulm

            @Aslund said in Using Qt Test and private members:

            QSqlDatabase

            is a singleton and contains all databases you created. So, why do you need a pointer to a QSqlDatabase?
            See https://doc.qt.io/qt-5/qsqldatabase.html

            // Add database
            QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
            db.setHostName("acidalia");
            db.setDatabaseName("customdb");
            db.setUserName("mojito");
            db.setPassword("J0a1m8");
            bool ok = db.open();
            ...
            // Here you get your database
            QSqlDatabase db = QSqlDatabase::database();
            
            AslundA Offline
            AslundA Offline
            Aslund
            wrote on last edited by
            #5

            @jsulm

            Hey Jsulm

            Thank you for clearing it up. Makes sense now. I missed the fact that QSqlDatabase is a singleton. Rereading the documentation I can also see the following statement.

            Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior.

            1 Reply Last reply
            2

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved