Skip to content

Instantly share code, notes, and snippets.

@gskema
Last active March 9, 2018 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gskema/cd0651ca42ef8f047df3277aa95a2f21 to your computer and use it in GitHub Desktop.
Save gskema/cd0651ca42ef8f047df3277aa95a2f21 to your computer and use it in GitHub Desktop.
Automatically tests basic setters/getters, assumes your test namespace matches the tested class namespaces. Tests setter with 1 parameter only.
<?php
namespace Acme;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionMethod;
use ReflectionType;
use RuntimeException;
trait GetterSetterTestingTrait
{
public function testGettersSetters()
{
/** @var TestCase $test */
$test = $this;
$className = substr(get_class($this), 0, -4);
if (!class_exists($className)) {
throw new RuntimeException(sprintf('Class %s not found, cannot test getters/setters', $className));
}
$testedObject = $test
->getMockBuilder($className)
->disableOriginalConstructor()
->setMethods(null)
->getMock();
$refClass = new ReflectionClass($className);
$testableMethods = [];
foreach ($refClass->getProperties() as $refProperty) {
$propertyName = $refProperty->getName();
$getterName = 'get'.ucfirst($propertyName);
$setterName = 'set'.ucfirst($propertyName);
if ($refClass->hasMethod($getterName) && $refClass->hasMethod($setterName)) {
$testableMethods[] = [$getterName, $setterName];
}
}
foreach ($testableMethods as list($getterName, $setterName)) {
$refSetter = new ReflectionMethod($className, $setterName);
$refParams = $refSetter->getParameters();
if (1 === count($refParams)) {
$refParam = $refParams[0];
$expectedValues = [];
$expectedValues[] = $this->getParamMock($refParam->getType());
if ($refParam->allowsNull() && null !== $refParam->getType()) {
$expectedValues[] = null;
}
foreach ($expectedValues as $expectedValue) {
$testedObject->{$setterName}($expectedValue);
$actualValue = $testedObject->{$getterName}();
$message = sprintf(
'Expected %s() value to equal %s (set using %s), got %s',
$getterName,
print_r($expectedValue, 1),
$setterName,
print_r($actualValue, 1)
);
$test->assertEquals($expectedValue, $actualValue, $message);
}
}
}
}
private function getParamMock(ReflectionType $refType)
{
/** @var TestCase $test */
$test = $this;
$type = $refType->getName();
if (interface_exists($type)) {
return $test->getMockBuilder($type)->getMockForAbstractClass();
}
switch ($type) {
case 'NULL':
return 'null';
case 'boolean':
return (bool)rand(0, 1);
case 'integer':
return random_int(1, 100);
case 'string':
return str_shuffle('abcdefghijklmnopqrstuvxyz0123456789');
case 'array':
return [];
default:
return $test->getMockBuilder($refType)->disableOriginalConstructor()->getMock();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment