Skip to content

Commit c0be99a

Browse files
committed
gram
1 parent 2e8b0ab commit c0be99a

File tree

1 file changed

+35
-35
lines changed

1 file changed

+35
-35
lines changed

resources/blog/posts/2026/2026-02-07-upgrade-to-phpunit-125-in-7-diffs.md

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
---
22
id: 83
3-
title: "Upgrade to PHPUnit 12.5 in 7 diffs"
3+
title: "Upgrade to PHPUnit 12.5 in 7 Diffs"
44
perex: |
5-
PHPUnit 12 was released a year ago, but only PHPUnit 12.5 released in December 2025 includes valuable features that are worth the once a year ugprade.
5+
PHPUnit 12 was released a year ago, but only PHPUnit 12.5 released in December 2025 includes valuable features that are worth it.
66
7-
The most important change, that will affect your code, is that mocks are now much more strict. And there also stubs... a mock that does not nothing. How to spot them and separate them?
7+
The most important change, that will affect your code, is that mocks are now much stricter. There are also stubs, a mock that does nothing. How do you spot them and separate them?
88
9-
Are you curious how to get from 4000 notices to under 100 in 7 diffs? Read on.
9+
Curious how to get from 4000 notices to under 100 in 7 diffs? Read on.
1010
---
1111

12-
What is difference between a mock and a stub? You didn't have to care untill PHPUnit 12.5, but now you do.
12+
What is the difference between a mock and a stub? You did not have to care until PHPUnit 12.5, but now you do.
1313

14-
Why? Because PHPUnit now complains their miss-use verboselly. And there is no way to ignore it:
14+
Why? Because PHPUnit now complains about their misuse very verbosely. There is no way to ignore it:
1515

1616
<img src="/assets/images/blog/2026/phpunit-notices-spam.png" class="img-thumbnail" style="max-width: 20em">
1717

@@ -26,7 +26,7 @@ There is more precise definition in the PHPUnit docs, but in plain English:
2626

2727
<br>
2828

29-
* **a mock** is a fake class, that has expectations of being called or not being called,
29+
* **A mock** is a fake class that has expectations about being called or not being called,
3030

3131
```php
3232
$someMock = $this->createMock(SomeClass::class);
@@ -39,7 +39,7 @@ Here we expect the `someMethod` to be called. PHPUnit will crash with error othe
3939

4040
<br>
4141

42-
* **a stub** is also a fake class, but it doesn't do anything at all.
42+
* **A stub** is also a fake class, but it does not do anything at all.
4343

4444
We can use it to make comply with constructor requirements:
4545

@@ -60,13 +60,13 @@ $this->assertSame($request, $requestStack->getCurrentRequest());
6060

6161
<br>
6262

63-
This leads us to first simplest change we can do.
63+
This leads us to the first and simplest change we can make.
6464

6565
<br>
6666

67-
## 1. Use `createStub()` over `createMock()` in args
67+
## 1. Use `createStub()` instead of `createMock()` in arguments
6868

69-
The first one are simple as:
69+
The first cases are as simple as:
7070

7171
```diff
7272
$someClass = new SomeClass(
@@ -86,7 +86,7 @@ Also variable assigns:
8686
$someClass = new SomeClass($someDependency);
8787
```
8888

89-
Or coalesce as argument:
89+
Or coalesce directly in the argument:
9090

9191
```diff
9292
-$someClass = new SomeClass(
@@ -117,9 +117,9 @@ But also property fetches without any expectations:
117117

118118
## 2. Inline once-used Mocks Property to a Variable
119119

120-
This is not change in PHPUnit 12.5 per se, bit it helps with changes that come with it. During the upgrade, I've noticed some properties are used just once.
120+
This is not a change in PHPUnit 12.5 itself, but it helps with the changes that come with it. During the upgrade, I've noticed some properties are used just once.
121121

122-
Properties are not variables for one reason: to be used across multiple methods. So lets fix that:
122+
Properties are not variables for one reason: to be used across multiple methods. Let us fix that:
123123

124124
```diff
125125
-private MockObject $someDependency;
@@ -143,7 +143,7 @@ We have less code to read for us and GPT, and also can move to `createStub()` wi
143143

144144
<br>
145145

146-
## 3. Remove never used isolated mocks, as well as dead
146+
## 3. Remove never used isolated mocks and dead code
147147

148148
Speaking of dead code, the mocks to stub narrowign also surfaces another issue: never used mocks that live on their own island.
149149

@@ -158,9 +158,9 @@ $this->createMock(SomeClass::class)
158158
->willReturn(100);
159159
```
160160

161-
What is wrong with this code snippet, apart being a stub? It is never used. We created it, but we never assigned it to a variable, nor property feath, nor argument of a method call.
161+
What is wrong with this code snippet, apart from being a stub? It is never used. We created it, but we never assigned it to a variable, nor property feath, nor argument of a method call.
162162

163-
It's a dead code. Remove it:
163+
It is dead code. Remove it:
164164

165165
```diff
166166
-$this->createMock(SomeClass::class)
@@ -171,7 +171,7 @@ It's a dead code. Remove it:
171171

172172
<br>
173173

174-
Beware, this can be a as complex as well defined and typed property... that is never used. Dead code, remove it:
174+
Beware, this can be as complex as a well defined and typed property... that is never used. Dead code, remove it:
175175

176176
```diff
177177
-private MockObject $mockProperty;
@@ -189,7 +189,7 @@ Beware, this can be a as complex as well defined and typed property... that is n
189189

190190
## 4. From `$this->any()` to explicit expectations
191191

192-
PHPUnit now also deprecated used of `$this->any()` expectations. Wise choice, as its says "we expect 0, or 1 or any number of occurances". This code as well could be removed.
192+
PHPUnit now also deprecated used of `$this->any()` expectations. This is a wise choice, as it effectively says "we expect 0, 1, or any number of occurrences". This code as well could be removed.
193193

194194
<br>
195195

@@ -208,7 +208,7 @@ $someClass
208208
->willReturn(100);
209209
```
210210

211-
Both will be most reported by PHPUnit as stubs. They have 0 expectations (amongs other numbers). So how do we fix that? Change we used before will not be enought (nor working):
211+
Both will be most reported by PHPUnit as stubs. They have 0 expectations (among other numbers). So how do we fix that? Change we used before is not enough and will not work here:
212212

213213
```diff
214214
-$someClass = $this->createMock(SomeClass::class);
@@ -220,7 +220,7 @@ Both will be most reported by PHPUnit as stubs. They have 0 expectations (amongs
220220
We have to be honest here, and it might require to understand the code.
221221

222222
* Is it a dummy method defined in `setUp()` method, in case it will be called any further in the codebase?
223-
* Is it implicit `$this->any()`, just becaused we forgot to add explicit number?
223+
* Is it implicit `$this->any()`, just because we forgot to add explicit number?
224224

225225
<br>
226226

@@ -238,7 +238,7 @@ But what about the `setUp()` method? Do we have to now go through all the code a
238238
<br>
239239

240240

241-
## 5. Add `#[AllowMockObjectsWithoutExpectations]` for setUp() optionals
241+
## 5. Add `#[AllowMockObjectsWithoutExpectations]` for optional setUp mocks
242242

243243
It's perfectly reasonable to use `setUp()` method to create mock properties that may or may not be used in one of the test method later:
244244

@@ -267,8 +267,8 @@ public function testNotUsing()
267267
}
268268
```
269269

270-
Here we have one mocked object as a property with *any* expectations. Then 2 test methods. The 1st one is using mock as a mock.
271-
The 2nd test method is not, so it's a stub from its point of view.
270+
Here we have one mocked object as a property with *any* expectations. Then there are two test methods. The first one uses the mock as a mock.
271+
The second test method does not, so from its point of view it is a stub.
272272

273273
(Also, another method can be using the property, but never calling the mocked method, so it's a stub as well).
274274

@@ -293,14 +293,14 @@ This attribute will silence the notices about stubs in this test class.
293293

294294
<br>
295295

296-
We could use it on every case above, yes. But that would prevent us from obvious fixes and push the technical debt deeper under the rug with whole under our apparment.
296+
We could use it on every case above, yes. But that would prevent us from obvious fixes and push the technical debt deeper under the rug with a hole under our apartment.
297297

298298
<br>
299299

300300

301-
## 6. Cover Vendor `*TestCase` and Data Providers
301+
## 6. Cover vendor `*TestCase` classes and data providers
302302

303-
There are 2 more case where the `#[AllowMockObjectsWithoutExpectations]` attribute is needed and makes sense.
303+
There are two more cases where the `#[AllowMockObjectsWithoutExpectations]` attribute is needed and makes sense.
304304

305305
<br>
306306

@@ -318,7 +318,7 @@ We use a 3rd party test case class, that defines its "any" expectations for a re
318318

319319
<br>
320320

321-
The next is a test method that uses a data provider. The data provider usually tests edge-case values that may or may not trigger a method call:
321+
The next is a test method that uses a data provider. The data provider usually tests edge case values that may or may not trigger a method call:
322322

323323
```diff
324324
use PHPUnit\Framework\TestCase;
@@ -348,15 +348,15 @@ The next is a test method that uses a data provider. The data provider usually t
348348

349349
<br>
350350

351-
## 7. Move from Object mocking to... Objects
351+
## 7. Move from object mocking to real objects
352352

353353
<blockquote class="blockquote">
354354
"The best mock is no mock at all"
355355
</blockquote>
356356

357-
Before we event dived into PHPUnit upgrade, we first eliminated the obvious cases that don't need any mocking at all.
357+
Before we even started the PHPUnit upgrade, we first eliminated the obvious cases that don't need any mocking at all.
358358

359-
We looked for plain objects, DTOs, value objects, entities and documents and replacted them will 100 % real, natively typed objects.
359+
We looked for plain objects, DTOs, value objects, entities and documents and replaced them with real, natively typed objects.
360360

361361
<br>
362362

@@ -387,7 +387,7 @@ It can be as simple as using a simple `Request` directly:
387387

388388
<br>
389389

390-
Simple as that. Same applies for entity/document objects. Instead of hard-to-read gettter mocks, use real objects with real values and types:
390+
Simple as that. Same applies for entity/document objects. Instead of hard-to-read getter mocks, use real objects with real values and types:
391391

392392
```diff
393393
-$user = $this->createMock(User::class);
@@ -410,12 +410,12 @@ Simple as that. Same applies for entity/document objects. Instead of hard-to-rea
410410

411411
You can get the entity/document PHPStan spotter rule from `symplify/phpstan-rules` [here](https://github.com/symplify/phpstan-rules/blob/4b7aa41072850f9875b45272d263be3f4a183f40/src/Rules/Doctrine/NoDocumentMockingRule.php#L21).
412412

413-
Also, give a go to experimental [Rector rule](https://github.com/rectorphp/rector-phpunit/pull/629) that manages to change these mocks to entities. It's a real time-saver.
413+
Also, give a go to experimental [Rector rule](https://github.com/rectorphp/rector-phpunit/pull/629) that manages to change these mocks to entities. It is a real time saver.
414414

415415

416416
<br>
417417

418-
## Enjoy Automated Upgrade
418+
## Enjoy the Automated Upgrade
419419

420420
We automated most of this work above, so you can let your agent handle the rest of the edge-cases. To get there, first enable the `phpunitCodeQuality` prepared set in your `rector.php`:
421421

@@ -453,7 +453,7 @@ It will automatically pick up the PHPUnit version and apply [the 12.5 set](https
453453

454454
<br>
455455

456-
That's all folks. Hope you've enjoyed this manually-written post. I surelly did enjoy writing it.
456+
That's all folks. I hope you enjoyed this manually written post. I certainly enjoyed writing it.
457457

458458
As always, if you have improvement or bug report, head to Rector on Github and let us know.
459459

0 commit comments

Comments
 (0)