Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. How to unit test with functions loaded from win32 api?
QtWS25 Last Chance

How to unit test with functions loaded from win32 api?

Scheduled Pinned Locked Moved Unsolved C++ Gurus
5 Posts 4 Posters 931 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.
  • D Offline
    D Offline
    dk10124
    wrote on last edited by
    #1

    Hello, I am writing unit tests for some functions that use calls to functions derived form win32 api and securitybaseapi, specifically LogonUserW and ImpersonateUser. I am not sure how to stub these functions out to get the output that I desire. I have looked at Gmock and Deviare but is there a better approach for stubbing out these calls in my project?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      From the top of my head, you should have an abstraction that encapsulate these function so you can provide a mock object based on this abstraction for the tests and otherwise use the API based implementation when running the application.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        smalti
        wrote on last edited by
        #3

        If abstraction over the API is not an option, you might consider using the gmock-win32 library.

        1 Reply Last reply
        0
        • Paul ColbyP Offline
          Paul ColbyP Offline
          Paul Colby
          wrote on last edited by
          #4

          Hi @dk10124, as @SGaist suggested, some form of mocke-dependency injection would be ideal. For example, you could pass a function pointer to your function, where the function pointer defaults to &LogonUserW normally, but your tests can pass their own mock function equivalent (ie with the same signature as LogonUserW()) to the function being tested.

          Another option, which I don't necessarily recommend (it definitely has some disadvantages) is to use a macro. It's not something I would normally suggest, but actually kind of fits with win32 conventions.

          So first, a small step back: personally, I wouldn't call LogonUserW() directly. Although its less relevant today, for portability (and thus as you'll often within Qt's internal code), I would use the LogonUser() macro instead. The win32 convention (love it or hate it), is to provide two versions of most win32 functions - one with an A suffix for 8-bit "ASCII" char strings, and one with a W suffix for 16-bit "Wide" (aka UNICODE, aka UCS-2) char strings. So, for example, in the winbase.h header, you'll see:

          #ifdef UNICODE
          #define LogonUser LogonUserW
          #else
          #define LogonUser LogonUserA
          #endif
          

          So if, for example, you're code was to use LogonUser(), then you'd actually be calling a macro, and that macro could be conditionally redefined when unit-testing. Something like:

          #include <all the things>
          
          #ifdef QT_TESTLIB_LIB
          #undef LogonUser
          #define LogonUser LogonUserMock
          #endif
          
          // your code that uses LogonUser() ...
          

          One major disadvantage is that approach requires the code-under-test to be compiled and linked as part of the test project. That is, you can't link to the "release" binaries (*.o or *.lib / *.dll) since the macro replacement only happens at compile time (unless the code is header-only). Still, I present it as just another option, that might suite depending on your specific needs.

          Cheers.

          SGaistS 1 Reply Last reply
          1
          • JonBJ JonB referenced this topic on
          • Paul ColbyP Paul Colby

            Hi @dk10124, as @SGaist suggested, some form of mocke-dependency injection would be ideal. For example, you could pass a function pointer to your function, where the function pointer defaults to &LogonUserW normally, but your tests can pass their own mock function equivalent (ie with the same signature as LogonUserW()) to the function being tested.

            Another option, which I don't necessarily recommend (it definitely has some disadvantages) is to use a macro. It's not something I would normally suggest, but actually kind of fits with win32 conventions.

            So first, a small step back: personally, I wouldn't call LogonUserW() directly. Although its less relevant today, for portability (and thus as you'll often within Qt's internal code), I would use the LogonUser() macro instead. The win32 convention (love it or hate it), is to provide two versions of most win32 functions - one with an A suffix for 8-bit "ASCII" char strings, and one with a W suffix for 16-bit "Wide" (aka UNICODE, aka UCS-2) char strings. So, for example, in the winbase.h header, you'll see:

            #ifdef UNICODE
            #define LogonUser LogonUserW
            #else
            #define LogonUser LogonUserA
            #endif
            

            So if, for example, you're code was to use LogonUser(), then you'd actually be calling a macro, and that macro could be conditionally redefined when unit-testing. Something like:

            #include <all the things>
            
            #ifdef QT_TESTLIB_LIB
            #undef LogonUser
            #define LogonUser LogonUserMock
            #endif
            
            // your code that uses LogonUser() ...
            

            One major disadvantage is that approach requires the code-under-test to be compiled and linked as part of the test project. That is, you can't link to the "release" binaries (*.o or *.lib / *.dll) since the macro replacement only happens at compile time (unless the code is header-only). Still, I present it as just another option, that might suite depending on your specific needs.

            Cheers.

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Paul-Colby is hinting at something good. If you want to be able to cleanly test things, you should consider making a library with all your widgets and business logic and your application will be mainly a main.cpp file using that library. This will allow you to build a test suite for your library in a simpler fashion.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1

            • Login

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