Skip to content

Commit

Permalink
Merge pull request #254 from elliotchance/1.7.1/253-setproperty
Browse files Browse the repository at this point in the history
1.7.1/253 setproperty
  • Loading branch information
elliotchance committed Mar 9, 2015
2 parents ea6095f + efd38d7 commit 335c6bc
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/Concise/Mock/MockBuilder.php
Expand Up @@ -195,7 +195,7 @@ public function get()
$this->restoreState($mockInstance);

foreach ($this->properties as $name => $value) {
$mockInstance->$name = $value;
$this->testCase->setProperty($mockInstance, $name, $value);
}

return $mockInstance;
Expand Down
29 changes: 24 additions & 5 deletions src/Concise/TestCase.php
Expand Up @@ -12,6 +12,7 @@
use PHPUnit_Framework_TestCase;
use ReflectionClass;
use Concise\Mock\MockInterface;
use ReflectionException;

// Load the keyword cache before the test suite begins.
Keywords::load();
Expand Down Expand Up @@ -262,16 +263,34 @@ protected function getReflectionProperty($object, $property)
return $property;
}

protected function shouldAccessProperty($object, $property)
{
return property_exists($object, $property)
|| method_exists($object, '__get');
}

public function getProperty($object, $property)
{
$property = $this->getReflectionProperty($object, $property);
return $property->getValue($object);
try {
$property = $this->getReflectionProperty($object, $property);
return $property->getValue($object);
} catch (ReflectionException $e) {
if ($this->shouldAccessProperty($object, $property)) {
return $object->$property;
}

throw $e;
}
}

public function setProperty($object, $property, $value)
public function setProperty($object, $name, $value)
{
$property = $this->getReflectionProperty($object, $property);
$property->setValue($object, $value);
try {
$property = $this->getReflectionProperty($object, $name);
$property->setValue($object, $value);
} catch (ReflectionException $e) {
$object->$name = $value;
}
}

/**
Expand Down
67 changes: 67 additions & 0 deletions tests/Concise/Mock/BuilderPropertyTest.php
Expand Up @@ -2,6 +2,22 @@

namespace Concise\Mock;

class MagicProperty
{
public function __get($name)
{
if (!property_exists($this, $name)) {
return 'not_found';
}
return $this->$name;
}

public function __set($name, $value)
{
$this->$name = $value;
}
}

/**
* @group mocking
*/
Expand Down Expand Up @@ -138,4 +154,55 @@ public function testAPropertyNameMustBeAString(MockBuilder $builder, $type)
{
$builder->setProperty(123, 456);
}

/**
* @dataProvider allBuilders
*/
public function testSetAProtectedPropertyWhenCreatingTheMock(MockBuilder $builder, $type)
{
if (self::MOCK_INTERFACE === $type) {
$this->expectFailure("You cannot set a property on an interface");
}
$mock = $builder->setProperty('hidden', 'bar')
->get();
$this->assert($this->getProperty($mock, 'hidden'), equals, 'bar');
}

/**
* @dataProvider allBuilders
*/
public function testSetAPropertyThatDoesNotExistIsPermitted(MockBuilder $builder, $type)
{
if (self::MOCK_INTERFACE === $type) {
$this->expectFailure("You cannot set a property on an interface");
}
$mock = $builder->setProperty('does_not_exist', 'bar')
->get();
$this->assert($this->getProperty($mock, 'does_not_exist'), equals, 'bar');
}

/**
* @dataProvider allBuilders
*/
public function testNullPropertiesAreStillFound(MockBuilder $builder, $type)
{
if (self::MOCK_INTERFACE === $type) {
$this->expectFailure("You cannot set a property on an interface");
}
$mock = $builder->setProperty('does_not_exist', null)
->get();
$this->assert($this->getProperty($mock, 'does_not_exist'), is_null);
}

public function testPropertiesAreAlwaysFoundIfClassHasMagicGet()
{
$this->assert($this->getProperty(new MagicProperty(), 'does_not_exist'), equals, 'not_found');
}

public function testPropertiesAreAlwaysSetIfClassHasMagicSet()
{
$object = new MagicProperty();
$this->setProperty($object, 'foo', 'bar');
$this->assert($this->getProperty($object, 'foo'), equals, 'bar');
}
}

0 comments on commit 335c6bc

Please sign in to comment.