1

Possible Duplicate:
Best practices to test protected methods with PHPUnit

class Footer
{
  private $_isEnabled;

  public function __construct(){
    $this->_isEnabled = true;
  }

  public function disable(){
    $this->_isEnabled = false;
  }  
}

When I am writing a unit test for the disable function after I set _isEanabled to false, I want to assert whether or not it is false.

But how can I access $_isEnabled?

This is my test function:

public function testDisable(){
  $footer = new Footer();
  $footer->disable();
  $this->assertFalse($footer->_isEnable);
}
Community
  • 1
  • 1
Yasitha
  • 2,233
  • 4
  • 24
  • 36
  • I think this question should be reopened, there is a link in the comments of the accepted answer describing how to do this via reflection that can be turned into a real answer, and also the duplicate questions don't seem to exist any more – Isaac Dec 16 '20 at 03:02

3 Answers3

3

Short answer:

You cannot. That's what PRIVATE means...

Long answer:

You can do it using reflection:

http://php.net/manual/en/book.reflection.php

It is a bit complicated, though, and adds another layer prone to fail so it is not the best way for testing...

I rather prefer to create a getter function:

public function getEnabled() {
   return $this->_isEnabled;
}

But if you have not done it as simple, I think you do not want to create it... but given the alternatives, you may reconsider it.

Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53
  • Yes I know it.. This example is a simple one.. but the real one is more complex.. I want to get access to the private attributes. I did it for private methods using reflection class. But don't knw how to do it for attributes. – Yasitha Jul 01 '12 at 19:12
  • http://www.php.net/manual/en/reflectionclass.getproperties.php – Fran Marzoa Jul 01 '12 at 19:23
1

An accessible property has to be public, I think that is self explanatory. However, you might encounter code where protected and private properties seem accessible in a way similar to accessing public variables.

This is done using the magic getter method:

class Footer
{
    private $_isEnabled;

    public function __get($propName)
    {
        if (!isset($this->{$propName}))
        {
            throw new Exception($propName.' is not set');
        }
        return $this->{$propName};
    }
}

This magic method is invoked each time you try to access a property that either, doesn't exist or isn't public. In short:

$instance->_isEnabled;//will work.

You can alter this method as you like, so that, for example, the underscore isn't required anymore... there's tons of things you can do with this.
Refer to the man pages

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
1

I doubt getting points by this: the class is not "algebraically" complete. A public function isEnabled() is missing. If the unit test has no info about the state, then other class clients will also miss this info.

A unit test on something private does not help saying anything on the public API, but checks internal operation which should be obvious.

In general it is bad business having unit tests relying on the implementation; then reimplementation makes maintaining unit tests too.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138