Jon
Jon

Reputation: 8511

Unit Test - Referencing Class' Class' Variable

I am writing a unit test for a component, and am having trouble to fake some data. I am wondering if it is possible to reference a variable in another class' class?

Example of set-up:

Unit Test > Human > Sports > $this->option['duration']

I am writing a unit test for my Human class. The Human class calls the Sports class, and the Sports class references its own variable $this->option['duration']. I want to be able to modify the value of $this->option['duration'] from my Unit Test. I am wondering if this is even possible?

I have tried to create a mock class of Sports in my Unit Test, and set my desired value of $this->option['duration'] inside this mock class. I however have no idea how to inject my mock Sports class into my Unit Test.

class SportsMock extends Sports {
    $this->option[duration'] = 10;
}

Upvotes: 0

Views: 429

Answers (1)

aorcsik
aorcsik

Reputation: 15552

For this kind of mocking you need to have dependency injection (DI) possible on your classes.

What I mean is, your Human class should not instantiate Sports, but accept it in the constructor or - even better - through a setter method. This way you can easily create a mocked class, instantiate it and inject it into the instance of the class you want to test.

class Human {
    /* ... */
    function setSports(Sports $sports) {
        $this->sports = $sports;
        return $this;
    }
    /* ... */ 
}

Now in your tests, you extend from Sports, so that it would work with the setter.

/* You can override any function in the original, to return some mock data */
class MockSports extends Sports {
    public $mock_data = array();
    function original_function() {
       return $mock_data['original_function'];
    }
}

Though this might work fine for your needs, testing libraries usually come with proper mocking utilities, which make mocking even more convenient, but this doesn't change the fact, that DI makes it much easier to test your code.

Example:

function my_example_test() {
    $human = new Human();
    $mock_sports = new MockSports();
    $mock_sports->mock_data['original_function'] = 10;
    $human->setSports($mock_sports); // <-- here is the injection
    /* Below you can test if your human works like it should */
}

Upvotes: 1

Related Questions