mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-29 18:27:44 +08:00
Adds ModelFactory support for hyperf/testing
(#5894)
This commit is contained in:
parent
defa69f36c
commit
030405b092
@ -24,6 +24,7 @@
|
||||
- [#5815](https://github.com/hyperf/hyperf/pull/5815) Added alias as `mysql` for `pdo` in `hyperf/db`.
|
||||
- [#5849](https://github.com/hyperf/hyperf/pull/5849) Support for insert update and select using enums.
|
||||
- [#5855](https://github.com/hyperf/hyperf/pull/5855) Added `hyperf/closure-command` component.
|
||||
- [#5894](https://github.com/hyperf/hyperf/pull/5894) Added `model-factory` support for `hyperf/testing`.
|
||||
|
||||
## Optimized
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
"doctrine/instantiator": "^1.0",
|
||||
"egulias/email-validator": "^3.0",
|
||||
"elasticsearch/elasticsearch": "^7.0",
|
||||
"fakerphp/faker": "^1.23",
|
||||
"fig/http-message-util": "^1.1.2",
|
||||
"filp/whoops": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "~3.16.0",
|
||||
|
@ -32,6 +32,9 @@
|
||||
"hyperf/utils": "~3.1.0",
|
||||
"symfony/http-foundation": "^5.4|^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"fakerphp/faker": "Required to use Faker feature.(^1.23)"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
|
44
src/testing/src/Concerns/InteractsWithModelFactory.php
Normal file
44
src/testing/src/Concerns/InteractsWithModelFactory.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Testing\Concerns;
|
||||
|
||||
use Faker\Factory as FakerFactory;
|
||||
use Hyperf\Testing\ModelFactory;
|
||||
|
||||
trait InteractsWithModelFactory
|
||||
{
|
||||
protected ?ModelFactory $modelFactory = null;
|
||||
|
||||
protected string|array $factoryPath = BASE_PATH . '/database/factories';
|
||||
|
||||
protected function setUpInteractsWithModelFactory()
|
||||
{
|
||||
if (! class_exists(FakerFactory::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->modelFactory = ModelFactory::create(
|
||||
FakerFactory::create('en_US')
|
||||
);
|
||||
|
||||
foreach ((array) $this->factoryPath as $path) {
|
||||
if (is_dir($path)) {
|
||||
$this->modelFactory->load($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDownInteractsWithModelFactory()
|
||||
{
|
||||
$this->modelFactory = null;
|
||||
}
|
||||
}
|
53
src/testing/src/ModelFactory.php
Normal file
53
src/testing/src/ModelFactory.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace Hyperf\Testing;
|
||||
|
||||
use Faker\Generator;
|
||||
use Hyperf\Database\Model\Factory;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
class ModelFactory
|
||||
{
|
||||
public function __construct(protected Factory $factory)
|
||||
{
|
||||
}
|
||||
|
||||
public static function create(Generator $faker)
|
||||
{
|
||||
return new static(new Factory($faker));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<T> $model
|
||||
* @return T
|
||||
*/
|
||||
public function factory(string $model, ...$arguments)
|
||||
{
|
||||
$factory = $this->factory;
|
||||
|
||||
if (isset($arguments[1]) && is_string($arguments[1])) {
|
||||
return $factory->of($arguments[0], $arguments[1])->times($arguments[2] ?? null);
|
||||
}
|
||||
if (isset($arguments[1])) {
|
||||
return $factory->of($arguments[0])->times($arguments[1]);
|
||||
}
|
||||
|
||||
return $factory->of($arguments[0]);
|
||||
}
|
||||
|
||||
public function load(string $path): void
|
||||
{
|
||||
$this->factory->load($path);
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@ namespace Hyperf\Testing;
|
||||
use Mockery as m;
|
||||
use Throwable;
|
||||
|
||||
use function Hyperf\Support\class_basename;
|
||||
use function Hyperf\Support\class_uses_recursive;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
@ -21,21 +24,95 @@ use Throwable;
|
||||
abstract class TestCase extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
use Concerns\InteractsWithContainer;
|
||||
use Concerns\InteractsWithModelFactory;
|
||||
use Concerns\MakesHttpRequests;
|
||||
use Concerns\RunTestsInCoroutine;
|
||||
|
||||
/**
|
||||
* The callbacks that should be run after the application is created.
|
||||
*/
|
||||
protected array $afterApplicationCreatedCallbacks = [];
|
||||
|
||||
/**
|
||||
* The callbacks that should be run before the application is destroyed.
|
||||
*/
|
||||
protected array $beforeApplicationDestroyedCallbacks = [];
|
||||
|
||||
/**
|
||||
* The exception thrown while running an application destruction callback.
|
||||
*/
|
||||
protected ?Throwable $callbackException = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->refreshContainer();
|
||||
|
||||
$this->setUpTraits();
|
||||
|
||||
foreach ($this->afterApplicationCreatedCallbacks as $callback) {
|
||||
$callback();
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->flushContainer();
|
||||
|
||||
$this->callBeforeApplicationDestroyedCallbacks();
|
||||
|
||||
try {
|
||||
m::close();
|
||||
} catch (Throwable) {
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
|
||||
if ($this->callbackException) {
|
||||
throw $this->callbackException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the testing helper traits.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function setUpTraits()
|
||||
{
|
||||
$uses = array_flip(class_uses_recursive(static::class));
|
||||
|
||||
foreach ($uses as $trait) {
|
||||
if (method_exists($this, $method = 'setUp' . class_basename($trait))) {
|
||||
$this->{$method}();
|
||||
}
|
||||
|
||||
if (method_exists($this, $method = 'tearDown' . class_basename($trait))) {
|
||||
$this->beforeApplicationDestroyed(fn () => $this->{$method}());
|
||||
}
|
||||
}
|
||||
|
||||
return $uses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be run before the application is destroyed.
|
||||
*/
|
||||
protected function beforeApplicationDestroyed(callable $callback)
|
||||
{
|
||||
$this->beforeApplicationDestroyedCallbacks[] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the application's pre-destruction callbacks.
|
||||
*/
|
||||
protected function callBeforeApplicationDestroyedCallbacks()
|
||||
{
|
||||
foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
|
||||
try {
|
||||
$callback();
|
||||
} catch (Throwable $e) {
|
||||
if (! $this->callbackException) {
|
||||
$this->callbackException = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user