-2

I try to run several tests in once (using GoogleTest) on source code I wrote containing static const variable initialized through network (which is "mocked" to imitate real behavior).

Example static const std::string myStr{getNameFromNetwork()};

The fact is in the first test the mock on getNameFromNetwork() is OK, but from the second to the last test, the mock is too much because the variable is static AND already initialized.

Do you have any proposal to solve this problem ?

Meugiwara
  • 599
  • 1
  • 7
  • 13

1 Answers1

0

Shortly put: get rid of ALL your global data, since as you have found out global data makes testing difficult. The solution you are looking for is called dependency injection. Summary : Put all your previous data in an object with a standardized interface and inject that into the code that needs the data. And read your data through that interface.

Example :

#include <iostream>
#include <string>

// remove ALL you globals
// static const std::string myStr{ getNameFromNetwork() }; <== remove ALL globals

// define an interface (abstract baseclass) with getters to your data
struct global_data_itf
{
    virtual const std::string& get_name_from_network() const = 0;
    virtual ~global_data_itf() = default;

protected:
    global_data_itf() = default;
};

//-----------------------------------------------------------------------------
// provide an implementation with all your previous global settings

struct global_data :
    global_data_itf
{
    const std::string& get_name_from_network() const override
    {
        return myStr;
    }

    std::string myStr{ "network_name" };
};

//-----------------------------------------------------------------------------

class your_class
{
public:

    your_class(const global_data_itf& data) :
        m_data{ data }
    {
    }

    void connect()
    {
        // instead of using static data use data from injected interface
        std::cout << m_data.get_name_from_network() << std::endl;
    }

private:
    const global_data_itf& m_data;
};

//-----------------------------------------------------------------------------
// test with default values

void test_case_1()
{
    global_data data;
    your_class object(data);

    object.connect();
}

//-----------------------------------------------------------------------------
// if you need to test with different configs/global data
// just instantiate a mock in you rest case

struct global_data_mock :
    global_data_itf
{
    const std::string& get_name_from_network() const override
    {
        return myStr;
    }

    std::string myStr{ "some other network name" };
};

void test_case_2()
{
    global_data_mock data;
    your_class object(data);
    object.connect();
}

//-----------------------------------------------------------------------------

int main()
{
    test_case_1();
    test_case_2();
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19