Skip to content

Commit 2dc923f

Browse files
Closes #3676
1 parent ecf25c3 commit 2dc923f

12 files changed

Lines changed: 65 additions & 32 deletions

File tree

ChangeLog-13.1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes of the PHPUnit 13.1 release series are documented in this fi
44

55
## [13.1.1] - 2026-MM-DD
66

7+
### Changed
8+
9+
* [#3676](https://github.com/sebastianbergmann/phpunit/issues/3676): Include class/interface name in mock object expectation failure messages
10+
711
### Fixed
812

913
* [#6019](https://github.com/sebastianbergmann/phpunit/issues/6019): `--migrate-configuration` does not update schema location when XML content already validates against current schema

src/Framework/MockObject/Generator/Generator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public function testDouble(string $type, bool $mockObject, ?array $methods = [],
109109

110110
$object = $this->instantiate(
111111
$mock,
112+
$type,
112113
$callOriginalConstructor,
113114
$arguments,
114115
$returnValueGeneration,
@@ -288,7 +289,7 @@ private function userDefinedInterfaceMethods(string $interfaceName): array
288289
* @throws ReflectionException
289290
* @throws RuntimeException
290291
*/
291-
private function instantiate(DoubledClass $mockClass, bool $callOriginalConstructor, array $arguments, bool $returnValueGeneration, bool $isMockObject): object
292+
private function instantiate(DoubledClass $mockClass, string $type, bool $callOriginalConstructor, array $arguments, bool $returnValueGeneration, bool $isMockObject): object
292293
{
293294
$className = $mockClass->generate();
294295

@@ -311,7 +312,7 @@ private function instantiate(DoubledClass $mockClass, bool $callOriginalConstruc
311312
*/
312313
$reflector->getProperty('__phpunit_state')->setValue(
313314
$object,
314-
new TestDoubleState($mockClass->configurableMethods(), $returnValueGeneration, $isMockObject),
315+
new TestDoubleState($mockClass->configurableMethods(), $type, $returnValueGeneration, $isMockObject),
315316
);
316317

317318
if ($callOriginalConstructor && $reflector->getConstructor() !== null) {

src/Framework/MockObject/Runtime/Api/StubApi.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ trait StubApi
2020

2121
public function __phpunit_state(): TestDoubleState
2222
{
23-
return $this->__phpunit_state ?? new TestDoubleState([], true, false);
23+
return $this->__phpunit_state ?? new TestDoubleState([], static::class, true, false);
2424
}
2525

2626
public function __phpunit_getInvocationHandler(): InvocationHandler

src/Framework/MockObject/Runtime/Api/TestDoubleState.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,23 @@ final class TestDoubleState
2020
* @var list<ConfigurableMethod>
2121
*/
2222
private readonly array $configurableMethods;
23+
24+
/**
25+
* @var class-string
26+
*/
27+
private readonly string $className;
2328
private readonly bool $generateReturnValues;
2429
private readonly bool $isMockObject;
2530
private ?InvocationHandler $invocationHandler = null;
2631

2732
/**
2833
* @param list<ConfigurableMethod> $configurableMethods
34+
* @param class-string $className
2935
*/
30-
public function __construct(array $configurableMethods, bool $generateReturnValues, bool $isMockObject = false)
36+
public function __construct(array $configurableMethods, string $className, bool $generateReturnValues, bool $isMockObject = false)
3137
{
3238
$this->configurableMethods = $configurableMethods;
39+
$this->className = $className;
3340
$this->generateReturnValues = $generateReturnValues;
3441
$this->isMockObject = $isMockObject;
3542
}
@@ -42,6 +49,7 @@ public function invocationHandler(): InvocationHandler
4249

4350
$this->invocationHandler = new InvocationHandler(
4451
$this->configurableMethods,
52+
$this->className,
4553
$this->generateReturnValues,
4654
$this->isMockObject,
4755
);

src/Framework/MockObject/Runtime/InvocationHandler.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,24 @@ final class InvocationHandler
4242
* @var list<ConfigurableMethod>
4343
*/
4444
private readonly array $configurableMethods;
45+
46+
/**
47+
* @var class-string
48+
*/
49+
private readonly string $className;
4550
private readonly bool $returnValueGeneration;
4651
private readonly bool $isMockObject;
4752
private bool $sealed = false;
4853
private ?AssertionFailedError $assertionFailure = null;
4954

5055
/**
5156
* @param list<ConfigurableMethod> $configurableMethods
57+
* @param class-string $className
5258
*/
53-
public function __construct(array $configurableMethods, bool $returnValueGeneration, bool $isMockObject = false)
59+
public function __construct(array $configurableMethods, string $className, bool $returnValueGeneration, bool $isMockObject = false)
5460
{
5561
$this->configurableMethods = $configurableMethods;
62+
$this->className = $className;
5663
$this->returnValueGeneration = $returnValueGeneration;
5764
$this->isMockObject = $isMockObject;
5865
}
@@ -114,7 +121,7 @@ public function expects(InvocationOrder $rule): InvocationMocker|InvocationStubb
114121
throw new TestDoubleSealedException;
115122
}
116123

117-
$matcher = new Matcher($rule);
124+
$matcher = new Matcher($rule, $this->className);
118125
$this->addMatcher($matcher);
119126

120127
if ($this->isMockObject) {
@@ -210,7 +217,7 @@ public function seal(bool $isMockObject): void
210217

211218
foreach ($this->configurableMethods as $method) {
212219
if (!in_array($method->name(), $configuredMethods, true)) {
213-
$matcher = new Matcher(new InvokedCount(0));
220+
$matcher = new Matcher(new InvokedCount(0), $this->className);
214221

215222
$matcher->setMethodNameRule(new MethodName($method->name()));
216223

src/Framework/MockObject/Runtime/Matcher.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ final class Matcher
3030
{
3131
private readonly InvocationOrder $invocationRule;
3232

33+
/**
34+
* @var class-string
35+
*/
36+
private readonly string $className;
37+
3338
/**
3439
* @var ?non-empty-string
3540
*/
@@ -38,9 +43,13 @@ final class Matcher
3843
private ?ParametersRule $parametersRule = null;
3944
private ?Stub $stub = null;
4045

41-
public function __construct(InvocationOrder $rule)
46+
/**
47+
* @param class-string $className
48+
*/
49+
public function __construct(InvocationOrder $rule, string $className)
4250
{
4351
$this->invocationRule = $rule;
52+
$this->className = $className;
4453
}
4554

4655
public function hasInvocationCountRule(): bool
@@ -130,7 +139,7 @@ public function invoked(Invocation $invocation): mixed
130139
throw new ExpectationFailedException(
131140
sprintf(
132141
"Expectation for %s failed.\n%s",
133-
$this->methodNameRule->failureDescription(),
142+
$this->methodNameRule->failureDescription($this->className),
134143
$e->getMessage(),
135144
),
136145
$e->getComparisonFailure(),
@@ -182,7 +191,7 @@ public function matches(Invocation $invocation): bool
182191
throw new ExpectationFailedException(
183192
sprintf(
184193
"Expectation for %s failed.\n%s",
185-
$this->methodNameRule->failureDescription(),
194+
$this->methodNameRule->failureDescription($this->className),
186195
$e->getMessage(),
187196
),
188197
$e->getComparisonFailure(),
@@ -221,7 +230,7 @@ public function verify(): void
221230
throw new ExpectationFailedException(
222231
sprintf(
223232
'%s was expected to be %s but was %s.',
224-
$this->methodNameRule->failureDescription(),
233+
$this->methodNameRule->failureDescription($this->className),
225234
$this->invocationRule->toString(),
226235
$invoked,
227236
),
@@ -243,7 +252,7 @@ public function verify(): void
243252
throw new ExpectationFailedException(
244253
sprintf(
245254
"Expectation for %s failed.\n%s",
246-
$this->methodNameRule->failureDescription(),
255+
$this->methodNameRule->failureDescription($this->className),
247256
ThrowableToStringMapper::map($e),
248257
),
249258
);

src/Framework/MockObject/Runtime/ReturnValueGenerator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ private function newInstanceOf(StubInternal $testStub, string $className, string
183183
$object,
184184
new TestDoubleState(
185185
$testStub->__phpunit_state()->configurableMethods(),
186+
$className,
186187
$testStub->__phpunit_state()->generateReturnValues(),
187188
),
188189
);

src/Framework/MockObject/Runtime/Rule/MethodName.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ public function toString(): string
4242
return 'method name ' . $this->constraint->toString();
4343
}
4444

45-
public function failureDescription(): string
45+
/**
46+
* @param class-string $className
47+
*/
48+
public function failureDescription(string $className): string
4649
{
4750
if ($this->constraint instanceof MethodNameConstraint) {
48-
return '"' . $this->constraint->methodName() . '()"';
51+
return $className . '::' . $this->constraint->methodName() . '()';
4952
}
5053

5154
return $this->toString();

tests/end-to-end/event/failed-mock-expectation.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Test Preparation Started (PHPUnit\TestFixture\Event\FailedExpectationTest::testO
2323
Test Prepared (PHPUnit\TestFixture\Event\FailedExpectationTest::testOne)
2424
Mock Object Created (PHPUnit\TestFixture\MockObject\AnInterface)
2525
Test Failed (PHPUnit\TestFixture\Event\FailedExpectationTest::testOne)
26-
"doSomething()" was expected to be invoked once but was never invoked.
26+
PHPUnit\TestFixture\MockObject\AnInterface::doSomething() was expected to be invoked once but was never invoked.
2727
Test Finished (PHPUnit\TestFixture\Event\FailedExpectationTest::testOne)
2828
Test Suite Finished (PHPUnit\TestFixture\Event\FailedExpectationTest, 1 test)
2929
Test Runner Execution Finished

tests/end-to-end/regression/6138.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Time: %s, Memory: %s
2121
There was 1 failure:
2222

2323
1) PHPUnit\TestFixture\Issue6138\Issue6138Test::testOne
24-
Expectation for "m()" failed.
24+
Expectation for PHPUnit\TestFixture\Issue6138\I::m() failed.
2525
Parameter $c for invocation PHPUnit\TestFixture\Issue6138\I::m(PHPUnit\TestFixture\Issue6138\C Object (...)): void does not match expected value.
2626
Failed asserting that two objects are equal.
2727
--- Expected

0 commit comments

Comments
 (0)