Refresh with Rector 0.18 features. The Rector set is currently not available, but the rest of article is still valid and useful.
I'm happy that more and more people try to use Rector upgrade and migrate their code-bases to the ones they really want for a long time.
Last week I was approached by 2 different people with single need - migrate their tests to PHPUnit.
"Nobody believes in anything without an inner feeling that it can be realized.
This is the only source of dreamlike powers."
Disclaimer: I never saw PhpSpec code before this mentoring session. All I learned was from my client and their needs (and bit of reading the documentation).
That was my question to one of my clients when I saw both PhpSpec and PHPUnit tests in its code base.
assertSame()
and shouldBeEqualTo()
"?But before I noticed PhpSpec and asked about it, we had another chat:
KernelTestCase
"?Then I explored PhpSpec and found out, it's basically PHPUnit with different naming.
"It looks like Y, a variant of X, could be done in
about half the time, and you lose only one feature."
Why did we choose to migrate PhpSpec tests to PHPUnit? Well, it's better obviously... Do you agree with me just because I wrote that? Don't do that, it's my personal opinionated opinion (= feeling, emotion). Ask me for some data instead.
Let's look at downloads:
But 117 mil. downloads can be like "You should use Windows XP because it's the most used Windows version ever!" That's classic manipulation of dying dinosaur.
Let's see the trends! In the same order:
Which one would you pick from this 2 information? I'd go for the last one, so did my client. So that's why we agreed to migrate PhpSpec (the middle one) to PHPUnit.
This is how 1 spec migration might look like:
<?php
-namespace spec\App\Product;
+namespace Tests\App\Product;
-use PhpSpec\ObjectBehavior;
-final class CategorySpec extends ObjectBehavior
+final class CategoryTest extends \PHPUnit\Framework\TestCase
{
+ /**
+ * @var \App\Product\Category
+ */
+ private $createMe;
- public function let()
+ protected function setUp()
{
- $this->beConstructedWith(5);
+ $this->createMe = new \App\Product\Category(5);
}
- public function it_returns_id()
+ public function testReturnsId()
{
- $this->id()->shouldReturn(5);
+ $this->assertSame(5, $this->createMe->id());
}
- public function it_blows()
+ public function testBlows()
{
- $this->shouldThrow('SomeException')->during('item', [5]);
+ $this->expectException('SomeException');
+ $this->createMe->item(5);
}
- public function it_should_be_called(Cart $cart)
+ public function testCalled()
{
+ /** @var Cart|\PHPUnit\Framework\MockObject\MockObject $cart */
+ $cart = $this->createMock(Cart::class);
- $cart->price()->shouldBeCalled()->willReturn(5);
+ $cart->expects($this->atLeastOnce())->method('price')->willReturn(5);
- $cart->shippingAddress(Argument::type(Address::class))->shouldBeCalled();
+ $cart->expects($this->atLeastOnce())->method('shippingAddress')->with($this->isType(Address::class));
}
- public function is_bool_check()
+ public function testBoolCheck()
{
- $this->hasFailed()->shouldBe(false);
+ $this->assertFalse($this->createMe->hasFailed());
- $this->hasFailed()->shouldNotBe(false);
+ $this->assertNotFalse($this->createMe->hasFailed());
}
- public function is_array_type()
+ public function testArrayType()
{
- $this->shippingAddresses()->shouldBeArray();
+ $this->assertIsIterable($this->createMe->shippingAddresses());
}
}
Pretty clear, right?
First, take a 2-week paid vacation... Just kidding. Start with Rector which migrates ~95 % of code cases. It also renames *Spec.php
to *Test.php
and moves them from /spec
to /tests
directory:
composer require rector/rector --dev
rector.php
configuse Rector\Set\ValueObject\SetList;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([SetList::PHPSPEC_TO_PHPUNIT]);
};
vendor/bin/rector process tests
Take couple of minutes to polish the rest of code and send PR to your project ✅
Happy coding!
Do you learn from my contents or use open-source packages like Rector every day?
Consider supporting it on GitHub Sponsors.
I'd really appreciate it!