How-To: Change Behavior of Instance Methods with Isolator++

The basis of the Isolator++ is the ability to change behavior of any method. Let’s look at an example for changing behavior of an instance method.

We want to test our Person object. While I’m using Person’s method to get the resulting country:

char* Person::GetCountry()

{

    return address->GetCountry();

}

I’m actually concentrating on the method MoveTo:

void Person::MoveTo(Address* newAddress)

{

    newAddress->Validate();

 

    if (newAddress->GetCountry() != "US")

    {

        throw ("Cannot move outside the US");

    }

    address = newAddress;

}

The Person has a dependency on the Address class – it uses it to validate and get information. The Address class looks like this:

#define CLASS_API __declspec(dllexport)

class CLASS_API  Address

{

private:

    const char* country = NULL;

 

public:

    char* GetCountry()

    {

        throw ("Not implemented yet!");

    }

 

    void Validate()

    {

        if (country == NULL)

        {

            throw (-12);

        }

    }

} 

There are two problems that make testing Person hard: The GetCountry method is not implemented and throws. The second is that Validate always throws on an uninitialized country.

Let’s look at the test. I’m testing the scenario where a Person moved to a valid address in the US. For that, I expect GetCountry to return US:

TEST_F(PersonTests, GetCountry_AfterMovingToValidUSAddress_ReturnUS)

{

    Person person;

    Address* usAddress = new Address();

    person.MoveTo(usAddress);

 

    char* country = person.GetCountry();

    bool result = strcmp (country, "US") ==0;

    ASSERT_TRUE(result);

}

This test crashes, because the Validate method throws. Let’s look at the test with Isolator++:

    1 TEST_F(PersonTests, GetCountry_AfterMovingToValidUSAddress_ReturnUS)

    2 {

    3     Person person;

    4     Address* usAddress = FAKE<Address>();

    5     WHEN_CALLED(usAddress->GetCountry()).ReturnPtr("US");

    6 

    7     person.MoveTo(usAddress);

    8 

    9     char* country = person.GetCountry();

   10     bool result = strcmp (country, "US") ==0;

   11     ASSERT_TRUE(result);

   12     ISOLATOR_CLEANUP();

   13 }

Let’s review the test:

  • In line 4, we declare a usAddress as fake. As a fake object, it ignores any void method, like Validate. That’s one problem solved.
  • In line 5 we solve the second problem. The GetCountry method usually throws,so we use WHEN_CALLED to return a fake value.
  • In line 12, we clean up all faking statements so they won’t affect the next tests.

By using Isolator++ APIs, we can actually simulate a US address, and test that the logic of Person works correctly.

Gil Zilberfeld