AspectMock - test any PHP code
And look:
(bool)true
var_dump($class instanceof DOMDocument); // => (bool)false
// а теперь немного магии
test::double('MySingleton', ['getInstance' => new DOMDocument]);
var_dump($class instanceof MySingleton); // => (bool)false
var_dump($class instanceof DOMDocument); // => (bool)true
?>
Oh no, we changed singleton! We redefined the static method. How to live now?
But the question now is different: how did we live before that?
Meet AspectMock . The easiest, but the most powerful framework for mocks and stubs in PHP.
Your new super-simple testing assistant. Based on Go AOP from NightTiger .
So, the idea of AspectMock is quite simple: to allow testing everything that was previously considered “bad practices” in PHP due to the impossibility of testing. Static methods, singleton, class methods - all this now lends itself to changes in real time. You can check the call of any method. Here is an example:
setName($name);
$user->save();
}
}
?>
Alas, we can’t make the unit test for this method using classical methods. Whatever we do, the save () method will be called, which will contact the database. However, in AspectMock this is not a problem at all.
null]));
$service = new UserService;
$service->createUserByName('davert');
$this->assertEquals('davert', $user->getName());
$user->verifyInvoked('save');
}
?>
The save method was called, but it was replaced by a dummy. We are satisfied, the base is intact, the username is assigned. 100% coverage, insulation present.
Why is this all?
PHP has a weird practice of treating any untestable code as bad. The example above shows that using the ActiveRecord pattern produces such untestable code. Is he bad? Well, a lie after all. Good pattern, implemented in many ORMs on different yachts.
The practice is strange in that 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 mind: how we will test it. And be sure to use Dependency Injection. Mandatory.
And now for a second, let's imagine that almost any OOP code in PHP lends itself to unit testing. Maybe we’d better focus on the readability of the code and its efficiency, instead of generating unnecessary services, injecting them, and then creating moki on them with multi-line constructs in PHPUnit?
However, the reality is that most developers relate to this issue more simply. They don’t write unit tests at all.
AspectMock lets you focus on writing efficient code. Of course, you must follow the correct architecture, the right standards, monitor the use of 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 practically nothing to study there. But Go AOP, about which you could already read on Habré , provides an excellent platform for integrating into any application methods through pointcut'ov. Based on our preferences, we can replace them with our dummies, as well as register their implementation. Go AOP creates proxy classes in real time and embeds them in a hierarchy. It works by changing autolading. 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 apply AspectMock?
Well, that's definitely not in production. AspectMock was created exclusively for testing, it is installed through the composer and works in PHPUnit and Codeception . How stable is AspectMock? Exactly the same as Go AOP itself. As you know, the project is still very experimental. The current version is 0.1.0. The most difficult thing is the initial installation. Try it, if everything started up for you, then it should work with a half kick.
Your feedback will be very interesting. Thanks for attention.
AspectMock lives on GitHub
Upd: There is a video demonstrating AspectMock in action.
Be sure to take a look, it's better to watch it than read it many times.
Only registered users can participate in the survey. Please come in.
What mocking libraries do you use?
- 39.3% PHPUnit 180
- 6.5% Mockery 30
- 1.9% Prophecy 9
- 0.8% Phaker 4
- 13.7% don't like moki at all 63
- 56.4% do not write unit tests 258