Skip to content

Commit

Permalink
Don't call constructors when stubbing objects
Browse files Browse the repository at this point in the history
We are/should already be specifying defaults for all the properties, so
it doesn't matter what the constructor does as we will be immediately
resetting the object state to our expected values anyway.

This is equivalent to e.g. Doctrine hydrating from a database record.
  • Loading branch information
acoulton committed Nov 27, 2024
1 parent 061cc10 commit 26553e8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Factory/DefaultStubFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function make(array $values, StubbingContext $context): object
$values = $this->getDefaultsMerger()->merge($defaults, $values, $context);

// Create the instance and apply customised values to it
$instance = $this->target_reflection->newInstance();
$instance = $this->target_reflection->newInstanceWithoutConstructor();
foreach ($values as $prop_name => $value) {
$this->castAndSetPropertyValue($prop_name, $context, $value, $instance);
}
Expand Down
51 changes: 51 additions & 0 deletions test/integration/SkipConstructorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace test\integration;

use DateTimeImmutable;
use Ingenerator\StubObjects\Attribute\StubDefault\StubDefaultValue;
use Ingenerator\StubObjects\StubObjects;
use PHPUnit\Framework\TestCase;

class SkipConstructorTest extends TestCase
{

public function test_it_can_stub_classes_that_have_constructor_args()
{
$result = $this->newSubject()->stub(MyStubbableClassWithConstructor::class);
$this->assertEquals(
[
'something_upper' => 'UPPER',
'nullable' => NULL,
'whenever' => new DateTimeImmutable('2024-02-02 10:30:04'),
'a_boolean' => FALSE,
],
(array) $result
);
}

private function newSubject(array $stubbable_class_patterns = ['*']): StubObjects
{
return new StubObjects(...get_defined_vars());
}
}


class MyStubbableClassWithConstructor
{
#[StubDefaultValue('UPPER')]
public string $something_upper;

public function __construct(
public ?string $nullable,
#[StubDefaultValue('2024-02-02 10:30:04')]
public DateTimeImmutable $whenever,
string $something_else,
// Note, we have to specify a default stub value because the =FALSE in the code is the *constructor param*
// default, technically it is not a default property value.
#[StubDefaultValue(FALSE)]
public bool $a_boolean = FALSE,
) {

}
}

0 comments on commit 26553e8

Please sign in to comment.