Nick
Nick

Reputation: 10143

How to access properties of object from Stub?

I have simple class:

class MyClass {

    private $myProperty;

    public __construct($propertyValue) {
        $this->myProperty= $propertyValue;
    }

    public function myMethod() {
        // Something
    }

}

And class what using MyClass:

class MySecondClass {

    private $myClass;

    public __construct($myClassInst) {
        $this->myClass = $myClassInst;
    }

    public function doIt() {
        $this->myClass->myMethod();
    }

}

And I have unit test for some MySecondClass class:

use Codeception\TestCase\Test;
use Codeception\Util\Stub;

class MySecondClassTest extends Test

    public function testDoIt() {
        $data = null;

        $myClass = Stub::construct('MyClass', ['propertyValue'], [
            'myMethod' => function() use (&$data) {
                // I want do that, but I can not!
                //$data = $this->myProperty;
            }

        $mySecondClass = new MySecondClass($myClass);
        $mySecondClass->doIt();

        $this->assertEquals($data, 'assertValue');
    ]);

}

If to uncomment lines in example above:

PHP Warning:  Uncaught PHPUnit_Framework_Exception: Undefined variable: myProperty ...

In case of myProperty is public:

PHPUnit_Framework_Exception: Undefined property: MySecondClassTest::$myProperty

Question: How to access property myProperty of MyClass from Stub if $this referencing to object of class MySecondClassTest there?

Upvotes: 0

Views: 461

Answers (1)

Alex Blex
Alex Blex

Reputation: 37038

Yagni. You are testing logic in MySecondClass::doIt ,not in MyClass.

You mock MyClass, and define exact response from MyClass::myMethod with constant value. Basically, your testDoIt() reads: Given we have an instance of MyClass that return some exact value, we expect MySecondClass::doIt to return some exact value. That's it. Nothing to do with MyClass::myProperty at all.

EDIT in answer to the comment

In case of public property it is error too, because $this references to MySecondClassTest object: PHPUnit_Framework_Exception: Undefined property: MySecondClassTest::$myProperty

First of all, I think you misunderstand concept of test doubles. Stub is not an instance of the mocked class. It is a stub. It imitates behaviour of the mocked class, and only in the defined part.

Secondly, $this in a closure always refers to the class where the closure is defined. In your case it is MySecondClassTest.

Again, the problem is not in visibility of the property, but in the fact that you need value of this property in your test. You do not. It violates the core principle of unittesting.

Upvotes: 1

Related Questions