New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to create Interceptor class? #5
Comments
👍 Trying to get it, but it's kinda difficult 😓 |
It's difficult to provide a generic answer here since each custom autoloader will require a custom answer. For example if you are not using composer, you'll need to rool you own Then you will need to roll your own <?php
use filter\Filter;
// The original code for composer is there
// https://github.com/crysalead/kahlan/blob/master/src/cli/Kahlan.php#L312-320
Filter::register('my.custom.interceptor', function($chain) {
Interceptor::patch([
'loader' => [$this->_autoloader, 'loadClass'],
'loadClass' => 'loadClass', // To change according your custom loader
'findFile' => 'findFile', // To change according your custom loader
'add' => 'add', // To change according your custom loader
'addPsr4' => 'addPsr4', // To change according your custom loader
'getPrefixes' => 'getPrefixes', // To change according your custom loader
'getPrefixesPsr4' => 'getPrefixesPsr4', // To change according your custom loader
'include' => $this->args()->get('include'),
'exclude' => array_merge($this->args()->get('exclude'), ['kahlan\\']),
'persistent' => $this->args()->get('persistent'),
'cachePath' => rtrim(sys_get_temp_dir(), DS) . DS . 'kahlan'
]);
});
// Apply the logic to the `'autoloader'` entry point.
Filter::apply($this, 'autoloader', 'my.custom.interceptor'); This way, this filter will replace the original code. If I remember right, only 'loadClass' && 'findFile' are required to run specs but if your custom autoloader is not able to provide a full mapping over the Composer API, you will get into trouble with the code coverage reporter. |
@jails it seems like a bad idea to "hack" a code inside of a binary to provide a stubbing inside specs. Don't you think so? On my case - if i using a Phalcon framework i think i need rewrite a composer compatible autoloader to work with your stubs? |
Since the Phalcon framework autoloader is a fully PSR-0 compliant why not using your Phalcon autoloader for your application and simply using the Composer autoloader for running the specs ? /**
* Adds some "extra" namespaces to the autoloader (i.e. for the ones whih are not in the composer.json)
*/
Filter::register('yourproject.namespaces', function($chain) {
// Register your PSR-0 namespaces
$this->_autoloader->add('YourNamespace\\', 'you/project/path');
// And you will probably need a constant like the following to bail out the Phalcon autoloader initialisation when you are in test mode.
define('KAHLAN_ENVIRONMENT', 'true');
});
Filter::apply($this, 'namespaces', 'yourproject.namespaces'); I used this strategy for a li3 project. Indeed since the lithium autoloader is also PSR-0 compatible both kind of autoloaders can do the job the same way. |
@jails <?php
use filter\Filter;
Filter::register('app.namespaces', function($chain) {
$this->_autoloader->add('Api\\Models\\', __DIR__ . '/app/models/');
});
Filter::apply($this, 'namespaces', 'app.namespaces'); In some of my tests i am creating $a = new \Api\Models\Payments(); And i got following error:
But it has a file |
It's probably related to some miss typing somewhere, you should try this: Filter::register('app.namespaces', function($chain) {
$this->_autoloader->add('Api\\Models\\', __DIR__ . '/app/models/');
echo $this->_autoloader->findFile('Api\Models\Payments') . "\n";
echo class_exists('Api\Models\Payments') . "\n";
exit();
}); It should echo the path Composer is looking for and |
I tried this, and all show me a
In Payment model i have: namespace Api\Models;
class Payments {} |
@jails
It's adding a namespace |
Fixed it, by adding not PSR-4 compatible namespaces. |
Cool, indeed the tree structure you provided didn't follow a PSR-0 convention, you had to either change it to a PSR-0 compatible structure or use the composer |
@jails Stub::on('Api\Models\Payments')->method('save')->andReturn(true);
$a = new \Api\Models\Payments();
var_dump($a->save()); It will dump |
Here a minimal example https://github.com/jails/temp |
@jails |
Ah indeed, but there's different way to play with Kahlan. For example you can also dynamically add a |
@jails public function test($a) {
return false;
} And then i trying to stub it: Stub::on('Api\Models\Payment')->method('test', function($a) {
return true;
});
$b = new \Api\Models\Payments();
var_dump($b->test('lol')); And i'll got a public function save($data=null, $whiteList=null){ }
public function create($data=null, $whiteList=null){ } How must i stub them correctly? |
you miss typed $b = new \Api\Models\Payments();
Stub::on($b)->method('test', function($a) {
return true;
});
expect($b->test('lol'))->toBe(true); would be more appropriate. |
@jails Stub::on('Api\Models\Payments')->method('save', function($data=null, $whitelist=null) {
return true;
});
$b = new \Api\Models\Payments();
var_dump($b->save()); And in my model i have this override: public function save($data=null, $whitelist=null) {
return parent::save($data, $whitelist);
} It works, when i comment this override it will not work. Do you have any ideas why? |
Because Kahlan is only able to stub PHP files. So if you comment the |
Ok, i get it. I just thinking how to solve this problem. Your way - normal, but if i got to test something like: <?php
class PaymentController extends \Phalcon\Mvc\Controller{
public function indexAction() {
$payment = new Payment();
if($payment->create()) {
throw \Exception('Some exception');
}
}
} Is there any way in my case to cover a bad creation? This line - |
Indeed in this scenario it's not possible since |
@jails |
Maybe it can be adapted as a patcher. For example this one replace all quit statements by a Kahlan's plugin call https://github.com/crysalead/kahlan/blob/master/src/jit/patcher/Quit.php. And applying a filter on the |
@jails |
@jails
How can i cover it? It's seems like a stupid question, but i dunno. |
@jails |
Q1: just use |
Q1: no, i am not asking about top describe, can i share some var in every *Spec.php scope? |
Imo with just plain PHP. At the bottom of your function di() {
static $di = new \Phalcon\DI();
return $di;
}
$di = di();
$di->set('mydatabase', ... ); Then use |
I'm closing this one, better to have one topic per issue only. |
👍 |
Is there any how-to documentation or samples?
The text was updated successfully, but these errors were encountered: