mercredi 3 août 2016

Unit Testing application interface to hardware - to mock or not

im very curious for peoples opinions on what way a software side application that interfaces with hardware should be unit tested.

For example, the main class of the software application "Connection" would be constructing a handle to a USB device.

I want to test the "Connection" class base function, say "OpenConnection" that would attempt to connect to a USB hardware device.

so far I have constructed a MOCK hardware device, and have included in my connection class a compiler flag, so if its built in unit test mode, it will use a mock object, otherwish it will use the actual hardware interface.

See example below

class TConnection
{
public:
    static TConnection* GetConnection();
    static void Shutdown();

    bool DidInitialise();

    bool Write(uint8_t* _pu8_buffer);
    bool Read(uint8_t* _pu8_buffer);

protected:
    TConnection();
    virtual ~TConnection();
    bool init();

private:
    static TConnection* mp_padConnection;
    static bool mb_DidInitialise;

#ifdef _UNIT_TEST_BUILD
    static mock_device* mp_handle;
#else
    static device* mp_handle;
#endif
};

then in the source file I include something like

#include "connection.h"

#ifdef _UNIT_TEST_BUILD
    mock_device* TConnection::mp_handle = nullptr;
#else
    device* TConnection::mp_handle = nullptr;
#endif // _UNIT_TEST_BUILD

TConnection::TConnection()
{
    ...
    init();
    ...
}

bool TConnection::init()
{
    mp_handle = hid_open( _VENDOR_ID, _PRODUCT_ID, nullptr );
    if (mp_hidHandle == nullptr) {
        return false;
    }
    if (hid_set_nonblocking(mp_hidHandle, _DISABLE_NB) == _ERROR_CODE) {
        return false;
    }
    return true;
}

The only thing I really dislike about my code is that my actual connection class contains test code. I would much prefer them to be separate.

Saying that, I also dont agree with having an entirely new mocked connection class written solely for the purpose of unit testing, it makes me feel like im just writting something designed to work as expected.

So I ask, what would be a better approach to testing such a class

Thank you in advance for your time and advice

Aucun commentaire:

Enregistrer un commentaire