Last active
April 26, 2023 20:37
-
-
Save jakzal/d601b419187e1d0db9af to your computer and use it in GitHub Desktop.
Test data builder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$defaultUser = (new UserBuilder())->build(); | |
$justRegisteredUser = UserBuilder::justRegistered()->withUsername('Anonymous')->build(); | |
$complexUser = (new UserBuilder()) | |
->withUsername('Test user') | |
->withEmail('[email protected]') | |
->build(); | |
$user = (new UserBuilder()) | |
->with(['username' => 'Test user']) | |
->build(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Acme\Builder; | |
class TestDataBuilder | |
{ | |
/** | |
* @var array | |
*/ | |
protected $defauts = []; | |
/** | |
* @var array | |
*/ | |
protected $data = []; | |
/** | |
* @return object | |
*/ | |
public function build() | |
{ | |
$data = array_merge($this->defaults, $this->data); | |
$entity = $this->instantiate(); | |
foreach ($data as $field => $value) { | |
$this->setObjectProperty($entity, $field, $value); | |
} | |
return $entity; | |
} | |
/** | |
* @param string $name | |
* @param array $arguments | |
* | |
* @return $this | |
* | |
* @throws \BadMethodCallException in case method is not supported | |
*/ | |
public function __call($name, $arguments) | |
{ | |
if (0 === strpos($name, 'with') && 1 === count($arguments)) { | |
$name = lcfirst(str_replace('with', '', $name)); | |
return $this->withProperty($name, $arguments[0]); | |
} | |
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s', static::class, $name)); | |
} | |
/** | |
* @param array $data | |
* | |
* @return $this | |
*/ | |
public function with(array $data) | |
{ | |
foreach ($data as $property => $value) { | |
$this->data[$property] = $value; | |
} | |
return $this; | |
} | |
/** | |
* @param string $name | |
* @param mixed $value | |
* | |
* @return $this | |
*/ | |
protected function withProperty($name, $value) | |
{ | |
$this->data[$name] = $value; | |
return $this; | |
} | |
/** | |
* @param object $object | |
* @param string $name | |
* @param mixed $value | |
*/ | |
protected function setObjectProperty($object, $name, $value) | |
{ | |
$property = new \ReflectionProperty(static::DATA_CLASS, $name); | |
$property->setAccessible(true); | |
$property->setValue($object, $value); | |
} | |
/** | |
* @return object | |
* | |
* @throws \RuntimeException in case the DATA_CLASS constant hasn't been set | |
*/ | |
protected function instantiate() | |
{ | |
if (!defined('static::DATA_CLASS')) { | |
throw new \RuntimeException(sprintf('Define DATA_CLASS constant for the %s', get_class($this))); | |
} | |
$class = static::DATA_CLASS; | |
return new $class(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Acme\Builder; | |
use Acme\User; | |
class UserBuilder extends TestDataBuilder | |
{ | |
const DATA_CLASS = User::class; | |
protected $defaults = [ | |
'username' => 'Kuba', | |
'email' => '[email protected]', | |
'registeredAt' => null, | |
'active' => true | |
]; | |
public function __construct() | |
{ | |
$this->defaults['registeredAt'] = new \DateTime('-1year'); | |
} | |
static public function justRegistered() | |
{ | |
return (new self()) | |
->withRegisteredAt(new \DateTime('now')); | |
} | |
public function withRegisteredAt(\DateTime $registeredAt) | |
{ | |
return $this->withProperty('registeredAt', $registeredAt); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is good stuff! Could you add a license to it? Otherwise it's difficult to use it in other projects. Thanks!