Comments (37)
Monkey patching only works if you are calling explicitly a "built-in function" or instantiating a "built-in class". But it doesn't work for "built-in inheritance" unfortunately. The only solution would be to introduce a new patcher imo (like described here).
from kahlan.
It looks like in solution line links is broken.
from kahlan.
It's just a comment of the issue nĀ°5
from kahlan.
You mean write a patcher something like Quit patcher and inject it into patcher namespace. https://github.com/crysalead/kahlan/blob/master/src/cli/Kahlan.php#L352-L365 like here?
from kahlan.
Yup, I mean a patcher which rewrite all:
class MyModel extends \Phalcon\Mvc\Model
to something like:
class MyModel extends \a\custom\layer\Class
The a\custom\layer\Class
class could be a class in your spec directory which extends Phalcon\Mvc\Model
with all its method overridden, or a more complex patcher should be able to create such class automatically. For example by using $layerClass = Stub::classname(['extends' => 'Phalcon\Mvc\Model'])
. Unfortunately Stub::classname()
won't work out of the box since right now the only "layered methods" are the abstract one but I think I can sketch up something quickly.
from kahlan.
Just updated the Stub class to allow a layer
parameter 6b4ba7a
So the deal is to have a patcher which is able to replace all extends \Phalcon\Mvc\Model
to extends \$layerClass
where $layerClass
is $layerClass = Stub::classname(['extends' => 'Phalcon\Mvc\Model', 'layer' => true])
. Btw the patcher will probably need to be configured with a list of fully namespaced class name to "layerize".
from kahlan.
And I sketched up the principle of a layer patcher in this commit f74002c in the dev branch.
from kahlan.
So on the dev branch adding the following:
...
$patchers->add('layer', new Layer([
'override' => [
'Phalcon\Mvc\Model'
]
]));
inside a patchers endpoint should allow you to stub any kind of model's methods extended from Phalcon\Mvc\Model
.
Feel free to keep me updated if this patcher still have room for improvement according to your specific usage with Phalcon.
from kahlan.
Iside config i set:
Filter::register('app.patchers', function($chain) {
$interceptor = Interceptor::instance();
$patchers = $interceptor->patchers();
$patchers->add('layer', new Layer([
'override' => [
'Phalcon\Mvc\Model'
]
]));
return $chain->next();
});
Then i have a model:
<?php
namespace Api\Models;
class ApiLog extends \Phalcon\Mvc\Model {
}
And spec:
<?php
use kahlan\plugin\Stub;
describe("Stub with a layer filter", function() {
it("should stub a layer", function() {
Stub::on('Api\Models\ApiLog')->method('create', function($data=null, $whiteList=null) {
return true;
});
$model = new \Api\Models\ApiLog();
expect($model->create())->toBe(true);
});
});
And it fails. (It return false
)
from kahlan.
After i clean-up /tmp/kalhan
it seems start working layering. But i got an error:
PHP Fatal error: Cannot override final method Phalcon\Mvc\Model::__construct() in /vagrant/crm/phalcon_test/temp/vendor/crysalead/kahlan/src/plugin/Stub.php(226) : eval()'d code on line 73
It seems that no need in layer to patch-up a finally
methods.
from kahlan.
Fixed this adding on plugin/Stub:432
line:
if ($method->getModifiers() & ReflectionMethod::IS_FINAL) continue;
And got new error:
PHP Fatal error: Declaration of kahlan\spec\plugin\stub\Stub0::assign() must be compatible with Phalcon\Mvc\ModelInterface::assign($data, $columnMap = NULL) in /vagrant/crm/phalcon_test/temp/vendor/crysalead/kahlan/src/plugin/Stub.php(226) : eval()'d code on line 72
from kahlan.
Fixed this. I will prepare a patch
from kahlan.
@jails it works now perfectly.
from kahlan.
On a second run i have:
PHP Fatal error: Class 'kahlan\spec\plugin\stub\Stub0' not found in /tmp/kahlan/vagrant/crm/wtm.dev/app/models/Cards.php on line 14
This line is:
class Cards extends \kahlan\spec\plugin\stub\Stub0 {
from kahlan.
Ah yeah indeed, didn't think about that, I guess we will need to embed the sub inside the cached file.
from kahlan.
I think it will be more handy to you.
from kahlan.
I thought about something like that 8a52782
It should work but wasn't able to test it since I haven't Phalcon installed.
from kahlan.
@jails it broken now. Just failing and that's all. I have a file, and it seems to be normal, but it just failing tests.
from kahlan.
@m1ome what the cached file in /tmp/kahlan
looks like ?
from kahlan.
@jails http://pastebin.com/0CWMBivr
from kahlan.
Now
PHP Parse error: syntax error, unexpected '<' in /tmp/kahlan/vagrant/crm/phalcon_test/temp/app/models/ApiLog.php on line 6
It looks like you generate <?php
twice.
from kahlan.
Ah yeah I fucked up the last dev commit.
from kahlan.
Should work better now but you will need to update https://github.com/crysalead/jit to its last master.
from kahlan.
@jails yes, now it's working as it should.
from kahlan.
@jails thank š !
from kahlan.
Cool, I'm merging it to master then.
from kahlan.
@jails Can u please help us with the undermentioned.
We are using Phalcon PHP for our website MVC Framework.
I am trying to test my all models and Controllers code using KAHLAN.
When I am trying to stub phalcon's Functions (FINDFIRST, GetRelated etc) it is not working.
I even put the API Patcher code in my kahlan-config.php which is given in
PATCHER CODE IN kahlan-config.php
Filter::register('api.patchers', function($chain) {
$interceptor = Interceptor::instance();
$patchers = $interceptor->patchers();
$patchers->add('layer', new Kahlan\Jit\Patcher\Layer([
'override' => [
'Phalcon\Mvc\Model'
]
]));
return $chain->next();
});
Filter::apply($this, 'patchers', 'api.patchers');
PFA my model and test files.
from kahlan.
@shivshankarsomu you need multiple steps for testing Phalcon
.
First of all you need to load your models to PSR4-autoloader:
Filter::register('app.namespaces', function($chain) {
$this->_autoloader->addPsr4('Api\\Models\\', __DIR__ . '/app/models/');
$this->_autoloader->addPsr4('Api\\Controllers\\V1\\', __DIR__ . '/app/controllers/v1/');
});
In e.g. we loading here models & controllers from directories, moving them to namespaces.
Second, you should add a Layer
to be able to Stub/Mock Phalcon
C-extension:
Filter::register('app.patchers', function($chain) {
$interceptor = Interceptor::instance();
$patchers = $interceptor->patchers();
$patchers->add('layer', new Layer([
'override' => [
'Phalcon\Mvc\Model'
]
]));
return $chain->next();
});
Third you should be CORRECT when passing parameters to stubbed method:
Stub::on('Api\Models\Cards')->method('::findFirst', function($params = null) {
$card = new stdClass();
$card->active = 1;
return $card;
});
As you see i am providing function($params = null)
and in your files you don't do such thing. For Stub
system it looks like method will be different from ::findFirst
that uses Phalcon
.
from kahlan.
@m1ome Thanks for the reply
I changed the code to this then also it is not working
$match_model = new Match();
$match_model->id = "2214";
Stub::on('Match Model')->method('::findFirst', function($params = null) {
return $match_model;
});
$series_model = new Series();
$series_model->id = "2223";
$series_model->series_type = "WC";
expect($series_model->func())->toBe($match_model);
Please help me with this
from kahlan.
@shivshankarsomu do you loading models like in my first step?
from kahlan.
@m1ome yes
PFB the code.
Filter::register('app.namespace', function($chain) {
$this->autoloader()->addPsr4('Model Layer\\' ,__DIR__ . 'db/');
$this->autoloader()->addPsr4('helpers Layer\\' ,__DIR__ . 'helpers/');
$this->autoloader()->addPsr4('Controllers Layer\\', __DIR__ . 'controllers/');
});
Filter::register('api.patchers', function($chain) {
$interceptor = Interceptor::instance();
$patchers = $interceptor->patchers();
$patchers->add('layer', new Kahlan\Jit\Patcher\Layer([
'override' => [
'Phalcon\Mvc\Model'
]
]));
return $chain->next();
});
Filter::apply($this, 'patchers', 'api.patchers');
Filter::apply($this, 'namespaces', 'app.namespace');
Its not working yet
from kahlan.
Can you please create a github repo with your code sample so we can clone it ? It'll be easier for us to get the issue by playing with your code.
from kahlan.
I had some configuration issue while mocking Phalcon ::findFirst which got fixed.
But now I am facing some issue while mocking Phalcon getRelated can you please share some examples of mocking Phalcon getRelated
from kahlan.
@shivshankarsomu https://github.com/phalcon/phalcon-devtools/blob/master/ide/2.0.9/Phalcon/mvc/Model.php#L1089
from kahlan.
Your stub should look like this:
$cards = Api\Models\Cards::findFirst();
Stub::on($cards)->method('getRelated', function($alias, $arguments = null) {
$card = new stdClass();
$card->active = 1;
return $card;
});
from kahlan.
Thanks for the help @m1ome @jails
It worked.
from kahlan.
@shivshankarsomu you are welcome. Next time please use another issue to ask a question. Feel free to do it.
from kahlan.
Related Issues (20)
- Throw exception test failed with Pipeline CI/CD HOT 2
- How to mock ZipArchive behavior HOT 4
- Expect to throw a `TypeError` got failed, `actual: TypeError, expected: TypeError` HOT 4
- Error with PHP 8 HOT 1
- Unable to run the tests when `XDEBUG_MODE` have multiple values HOT 1
- Feature Request: Support focusing a specific test or suite with command line arguments
- php 8.1 support HOT 2
- PHP Fatal error: Type of Kahlan\PhpErrorException::$file must be string (as in class Exception) in... HOT 3
- toBeCalled within Class Static Methods HOT 1
- Breakpoint; debugging tests HOT 4
- Missing default value 0 for int properties with PHP8 attributes in single line HOT 1
- Unable to stub without overriding function HOT 5
- Process exit with code 1 in github action HOT 2
- stub / Modify constante HOT 1
- PHP 8.2: dynamic properties HOT 3
- PHP 8.2 Function utf8_decode() is deprecated HOT 1
- Support for never return type (PHP 8.1+) HOT 5
- Cannot exclude autoloaded files from monkey patching
- Multiple _T_ATTRIBUTE tokens in single line HOT 1
- Bug: toHaveLength() does not work with accented letters and multi-byte strings HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kahlan.