Skip to content

Commit 51ed633

Browse files
committed
Fix FormTypeClassValidatorTest for PHPUnit 12.2 — replace ConstraintViolationBuilderInterface mock with concrete stub
PHPUnit 12.2 (CI) cannot configure methods with `static` return types via getMockBuilder; all fluent methods on ConstraintViolationBuilderInterface return `static`, so the mock setup threw MethodCannotBeConfiguredException. PHPUnit 12.5 (local) fixed this in the framework but the CI toolchain still uses 12.2. Replace the mock with a hand-written ConstraintViolationBuilderStub that records setParameter calls and the addViolation flag directly.
1 parent 44a9e3e commit 51ed633

1 file changed

Lines changed: 32 additions & 33 deletions

File tree

tests/Validator/Constraints/FormTypeClassValidatorTest.php

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@
2222
use Symfony\Component\Validator\Context\ExecutionContextInterface;
2323
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
2424

25+
/**
26+
* Concrete stub replacing getMockBuilder for ConstraintViolationBuilderInterface.
27+
* All fluent methods return `static` which PHPUnit <12.5 cannot mock.
28+
*/
29+
class ConstraintViolationBuilderStub implements ConstraintViolationBuilderInterface
30+
{
31+
public bool $violationAdded = false;
32+
public array $parameters = [];
33+
34+
public function atPath(string $path): static { return $this; }
35+
public function setParameter(string $key, string $value): static { $this->parameters[$key] = $value; return $this; }
36+
public function setParameters(array $parameters): static { return $this; }
37+
public function disableTranslation(): static { return $this; }
38+
public function setTranslationDomain(string $translationDomain): static { return $this; }
39+
public function setInvalidValue(mixed $invalidValue): static { return $this; }
40+
public function setPlural(int $number): static { return $this; }
41+
public function setCode(?string $code): static { return $this; }
42+
public function setCause(mixed $cause): static { return $this; }
43+
public function addViolation(): void { $this->violationAdded = true; }
44+
}
45+
2546
#[AllowMockObjectsWithoutExpectations]
2647
class FormTypeClassValidatorTest extends TestCase
2748
{
@@ -31,10 +52,8 @@ class FormTypeClassValidatorTest extends TestCase
3152
* @var ExecutionContextInterface|MockObject
3253
*/
3354
private MockObject $executionContextMock;
34-
/**
35-
* @var ConstraintViolationBuilderInterface|MockObject
36-
*/
37-
private MockObject $constraintViolationBuilderMock;
55+
56+
private ConstraintViolationBuilderStub $constraintViolationBuilderStub;
3857

3958
protected function setUp(): void
4059
{
@@ -44,20 +63,14 @@ protected function setUp(): void
4463
->disableOriginalConstructor()
4564
->getMock();
4665

47-
$this->constraintViolationBuilderMock = $this->getMockBuilder(ConstraintViolationBuilderInterface::class)
48-
->disableOriginalConstructor()
49-
->getMock();
66+
$this->constraintViolationBuilderStub = new ConstraintViolationBuilderStub();
5067
}
5168

5269
private function initializeValidatorForNoErrors(): void
5370
{
5471
$this->executionContextMock
5572
->expects($this->never())
5673
->method('buildViolation');
57-
58-
$this->constraintViolationBuilderMock
59-
->expects($this->never())
60-
->method('addViolation');
6174
$this->formTypeClassValidator->initialize($this->executionContextMock);
6275
}
6376

@@ -102,20 +115,13 @@ public function test_constraint_violation_for_invalid_class(): void
102115
->expects(self::once())
103116
->method('buildViolation')
104117
->with($constraint->message)
105-
->willReturn($this->constraintViolationBuilderMock);
118+
->willReturn($this->constraintViolationBuilderStub);
106119

107-
$this->constraintViolationBuilderMock
108-
->expects(self::once())
109-
->method('setParameter')
110-
->with('{{ string }}', __CLASS__)
111-
->willReturn($this->constraintViolationBuilderMock);
112-
113-
$this->constraintViolationBuilderMock
114-
->expects(self::once())
115-
->method('addViolation');
116120
$this->formTypeClassValidator->initialize($this->executionContextMock);
117-
118121
$this->formTypeClassValidator->validate(__CLASS__, $constraint);
122+
123+
$this->assertTrue($this->constraintViolationBuilderStub->violationAdded);
124+
$this->assertSame(__CLASS__, $this->constraintViolationBuilderStub->parameters['{{ string }}']);
119125
}
120126

121127
public function test_constraint_violation_for_string_that_is_not_a_class(): void
@@ -125,20 +131,13 @@ public function test_constraint_violation_for_string_that_is_not_a_class(): void
125131
$this->executionContextMock
126132
->expects(self::once())
127133
->method('buildViolation')
128-
->willReturn($this->constraintViolationBuilderMock);
134+
->willReturn($this->constraintViolationBuilderStub);
129135

130-
$this->constraintViolationBuilderMock
131-
->expects(self::once())
132-
->method('setParameter')
133-
->with('{{ string }}', 'NotAClass')
134-
->willReturn($this->constraintViolationBuilderMock);
135-
136-
$this->constraintViolationBuilderMock
137-
->expects(self::once())
138-
->method('addViolation');
139136
$this->formTypeClassValidator->initialize($this->executionContextMock);
140-
141137
$this->formTypeClassValidator->validate('NotAClass', $constraint);
138+
139+
$this->assertTrue($this->constraintViolationBuilderStub->violationAdded);
140+
$this->assertSame('NotAClass', $this->constraintViolationBuilderStub->parameters['{{ string }}']);
142141
}
143142

144143
public function test_form_type_class_options_passed_to_parent(): void

0 commit comments

Comments
 (0)