Skip to content

Commit 3a58f1e

Browse files
authored
Adding ResultMockFactory (#286)
* Adding ResultMockFactory * Bugfixes * Adding support for not adding all properties * cs * Revert debug code
1 parent ccf7c0a commit 3a58f1e

File tree

3 files changed

+201
-0
lines changed

3 files changed

+201
-0
lines changed

src/Test/ResultMockFactory.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AsyncAws\Core\Test;
6+
7+
use AsyncAws\Core\Result;
8+
9+
/**
10+
* An easy way to create Result objects for your tests.
11+
*
12+
* @author Tobias Nyholm <[email protected]>
13+
*/
14+
class ResultMockFactory
15+
{
16+
/**
17+
* Instantiate a Result class with some data.
18+
*
19+
* <code>
20+
* ResultMockFactory::create(SendEmailResponse::class, ['MessageId'=>'foo123']);
21+
* </code>
22+
*
23+
* @template T
24+
* @psalm-param class-string<T> $class
25+
*
26+
* @return T
27+
*/
28+
public static function create(string $class, array $data = [])
29+
{
30+
$parent = get_parent_class($class);
31+
if (false === $parent || Result::class !== $parent) {
32+
throw new \LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Result::class));
33+
}
34+
35+
$rereflectionClass = new \ReflectionClass($class);
36+
$object = $rereflectionClass->newInstanceWithoutConstructor();
37+
38+
foreach ($data as $propertyName => $propertyValue) {
39+
$property = $rereflectionClass->getProperty($propertyName);
40+
$property->setAccessible(true);
41+
$property->setValue($object, $propertyValue);
42+
}
43+
44+
self::addUndefinedProperties($rereflectionClass, $object, $data);
45+
46+
return $object;
47+
}
48+
49+
/**
50+
* Try to add some values to the properties not defined in $data.
51+
*
52+
* @throws \ReflectionException
53+
*/
54+
private static function addUndefinedProperties(\ReflectionClass $rereflectionClass, $object, array $data): void
55+
{
56+
foreach ($rereflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE) as $property) {
57+
if (\array_key_exists($property->getName(), $data)) {
58+
continue;
59+
}
60+
61+
$getter = $rereflectionClass->getMethod('get' . $property->getName());
62+
/** @psalm-suppress PossiblyNullReference */
63+
if (!$getter->hasReturnType() || $getter->getReturnType()->allowsNull()) {
64+
continue;
65+
}
66+
67+
/** @psalm-suppress PossiblyNullReference */
68+
switch ($getter->getReturnType()->getName()) {
69+
case 'int':
70+
$propertyValue = 0;
71+
72+
break;
73+
case 'string':
74+
$propertyValue = '';
75+
76+
break;
77+
case 'bool':
78+
$propertyValue = false;
79+
80+
break;
81+
case 'float':
82+
$propertyValue = 0.0;
83+
84+
break;
85+
case 'array':
86+
$propertyValue = [];
87+
88+
break;
89+
default:
90+
$propertyValue = null;
91+
92+
break;
93+
}
94+
95+
if (null !== $propertyValue) {
96+
$property->setAccessible(true);
97+
$property->setValue($object, $propertyValue);
98+
}
99+
}
100+
}
101+
}

tests/Resources/ExampleResponse.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AsyncAws\Core\Tests\Resources;
6+
7+
use AsyncAws\Core\Result;
8+
9+
class ExampleResponse extends Result
10+
{
11+
private $int;
12+
13+
private $float;
14+
15+
private $bool;
16+
17+
private $array;
18+
19+
private $string;
20+
21+
public function getInt(): int
22+
{
23+
return $this->int;
24+
}
25+
26+
public function getFloat(): float
27+
{
28+
return $this->float;
29+
}
30+
31+
public function getBool(): bool
32+
{
33+
return $this->bool;
34+
}
35+
36+
public function getArray(): array
37+
{
38+
return $this->array;
39+
}
40+
41+
public function getString(): string
42+
{
43+
return $this->string;
44+
}
45+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AsyncAws\Core\Tests\Unit\Test;
6+
7+
use AsyncAws\Core\Sts\Result\AssumedRoleUser;
8+
use AsyncAws\Core\Sts\Result\AssumeRoleResponse;
9+
use AsyncAws\Core\Test\ResultMockFactory;
10+
use AsyncAws\Core\Tests\Resources\ExampleResponse;
11+
use PHPUnit\Framework\TestCase;
12+
13+
class ResultMockFactoryTest extends TestCase
14+
{
15+
public function testCreate()
16+
{
17+
/** @var AssumeRoleResponse $result */
18+
$result = ResultMockFactory::create(AssumeRoleResponse::class, [
19+
'PackedPolicySize' => 342,
20+
]);
21+
22+
self::assertInstanceOf(AssumeRoleResponse::class, $result);
23+
self::assertNull($result->getAssumedRoleUser());
24+
self::assertEquals(342, $result->getPackedPolicySize());
25+
}
26+
27+
public function testCreateAndFillEmptyParams()
28+
{
29+
/** @var ExampleResponse $result */
30+
$result = ResultMockFactory::create(ExampleResponse::class);
31+
32+
self::assertEquals(0, $result->getInt());
33+
self::assertEquals([], $result->getArray());
34+
self::assertEquals(false, $result->getBool());
35+
self::assertEquals(0.0, $result->getFloat());
36+
self::assertEquals('', $result->getString());
37+
}
38+
39+
public function testCreateWithInvalidParameters()
40+
{
41+
$this->expectException(\ReflectionException::class);
42+
ResultMockFactory::create(AssumeRoleResponse::class, [
43+
'Foobar' => 'arn123',
44+
]);
45+
}
46+
47+
public function testCreateWithInvalidClass()
48+
{
49+
$this->expectException(\LogicException::class);
50+
ResultMockFactory::create(AssumedRoleUser::class, [
51+
'Arn' => 'arn123',
52+
'AssumedRoleId' => 'foo123',
53+
]);
54+
}
55+
}

0 commit comments

Comments
 (0)