AspectMock
Arba jei tau nepasisekė
Vaidas Mikalauskas

Jei tau pasisekė



O jeigu ne



<?php
class Whatever {
public static function registerNewUser(array $item) {
$user = new User;
$user->attributes = $item['user'];
if (Users::model()->countByAttributes($item['email']) > 0) {
throw new Exception('User with this email already exists');
}
if ($user->validate() && $user->save()) {
// password is hashed in `beforeSave()`
Yii::app()->mailer->send($user->email
new UserRegistrationNotification($user);
);
if ($user->isProUser()) {
$manager = new UserSubscriptionManager();
$manager->createSubscriptionPlan($user, $item['pro_details']);
}
if ($item['subscribe_to_newsletter']) {
Newsletters::subscribeUserToAll($user);
}
return true;
}
return false;
}
}
Dėl ko tau nepasisekė
- static function()
- new UserSubscriptionManager();
- Yii::app()
- User::model()
- Newsletters::subscribeUserToAll();
- depends on mailer, db, config, service managers, etc...
Nu neina pratestint!
AspectMock
Static functions:
<?php
function testStaticMethod() {
test::double('App\Users', ['tableName' => 'test_table']);
$this->assertEquals('test_table', \App\Users::tableName());
}
Global function overrides:
<?php
public function testGlobalOverrides()
{
test::double('App\Users', ['getFullName' => 'Peter']);
$user = new \App\Users;
$this->assertEquals('Peter', $user->getFullName());
}
Invocation testing
<?php
public function testStatic()
{
$double = test::double('App\Users', ['tableName' => 'test_table']);
$this->assertEquals('test_table', \App\Users::tableName());
$double->verifyInvoked('tableName');
$double->verifyNeverInvoked('save');
}
Install
{
"require": {
"codeception/aspect-mock": "0.4.2"
}
}Initialize
<?php
include __DIR__.'/../vendor/autoload.php'; // composer autoload
$kernel = \AspectMock\Kernel::getInstance();
$kernel->init(['includePaths' => [__DIR__.'/../src']]);Start using
<?php
use AspectMock\Test as Test;
Test::double('OfClass', ['methodName'=>'returnValue']) NOT BAD,
but how does it work?
Aspect-oriented programming
Code parsing
<?php
require 'myfile.php';
<?php
require 'php://read=go.source.transforming.loader/resource=myfile.php';
Behind the scenes
<?php
class User {
function setName($name)
{
$this->name = $name;
}
}<?php
class User {
function setName($name)
{ if (($__am_res = __amock_before($this, __CLASS__, __FUNCTION__, array($name.........
$this->name = $name;
}
}
Tips & Tricks
- Always test::clean()
- All best TDD practices still apply
- God classes are still evil
- If possible, limit AspectMock to "src/"
Should I use it?
NO
If you can
FAQ
Does AspectMock slows down tests?
YES
Ok, but can it mock ........ class/function/whatever?
YES
Does it require any special configuration or extensions?
NO
Thank you
Questions?
Aspect mock for PHP Kaunas
By Vaidas Mikalauskas
Aspect mock for PHP Kaunas
- 801


