How often do you write bikes? Can I join in here too? But the thing is, my bike is special. It would seem simple, three-wheeled, riveted in just one day. But there is one trick - it works on the engine from the car. What does he do?
And look:
<?php $class = MySingleton::getInstance(); var_dump($class instanceof MySingleton);
')
Oh no, we changed the singleton! We redefined the static method. How to live now?
But now the question is different: how did we live before?
Meet
AspectMock . The easiest, but most powerful framework for mocks and stubs for PHP.
Your new super simple test assistant. Based on
Go AOP from
NightTiger .
So, the idea of ​​AspectMock is quite simple: to allow testing everything that was previously considered to be “bad practices” in PHP due to the impossibility of testing. Static methods, singletons, class methods - all this is now subject to change in real time. You can check the call of any method. Here is an example:
<?php class UserService { function createUserByName($name) { $user = new User; $user->setName($name); $user->save(); } } ?>
Alas, but we cannot make a unit test for this method with classical means. Whatever we do, the save () method will be called, which will access the database. However, in AspectMock this is not a problem at all.
<?php function testUserCreate() { $user = test::double('User', ['save' => null])); $service = new UserService; $service->createUserByName('davert'); $this->assertEquals('davert', $user->getName()); $user->verifyInvoked('save'); } ?>
The save method was called, but it was replaced with a dummy. We are satisfied, the base is intact, the user name is assigned. Coverage 100%, insulation present.
Why is this all about?
There is a strange practice in PHP to consider any untested code to be bad. The example above shows that using the ActiveRecord pattern produces such untestable code. Is he bad? Well, not true after all. Good pattern, implemented in many ORM on different languages.
The practice is strange because the "testability" of the code is determined only by the technical limitations of the PHP language itself.
And therefore, before writing any code, you need to immediately keep in your head: how we will test it. And be sure to use Dependency Injection. Required.
And now for a moment, let's imagine that almost any OOP code in PHP is unit-tested. Maybe we’ll better focus on the readability of the code and its efficiency, instead of creating unnecessary services, injecting them, and then creating mocks on them with multi-line constructs in PHPUnit?
However, the reality is that most developers relate to this issue easier. They do not write unit tests at all.
AspectMock allows you to focus on writing efficient code. Of course, you have to follow the right architecture, the right standards, watch out for using dependencies, but you no longer need to artificially limit yourself to the technical capabilities of PHP. As one wonderful person said:
“Nothing is true. Everything is allowed."How it works?
AspectMock itself is very simple: only 8 files. There is almost nothing to learn. But Go AOP,
about which you could already read on Habré , provides an excellent platform to integrate into any application methods using pointcuts. Based on our preferences, we can replace them with our own dummies, as well as register their implementation. Go AOP in real time creates proxy classes and builds them into the hierarchy. Works by changing autoloading. Compatible with all popular frameworks:
Symfony2 ,
Zend Framework 2 ,
Yii ,
Laravel . If you are not familiar with Go Aop, I
highly recommend playing with it .
Where to use AspectMock?
Well, just not in production. AspectMock is created exclusively for testing, it is installed through a composer and works in
PHPUnit and
Codeception . How stable is AspectMock? Exactly as much as Go AOP itself. As you know, the project is still very experimental. The current version is 0.1.0. The most difficult is the initial installation. Try it, but if everything went wrong with you, you should continue to work from the floor of the kick.
Your feedback will be very interesting. Thanks for attention.
AspectMock dwells on githubUpd: There was a video showing AspectMock in actionBe sure to take a look, it's better to look than to read many times.