CakePHP test behaviour with mapped method
Asked Answered
K

1

2

Whilst creating an OwnableBehavior I decided to use the $mapMethods property that is available. It is to map any method called isOwnedByXXX() to isOwnedBy() (The link for the documentation on this is here)

Here is my OwnableBehavior code:

class OwnableBehavior extends Model Behavior {

    public $mapMethods = array('/isOwnedBy(\w+)/' => 'isOwnedBy');

    public function isOwnedBy(Model $model, $type, $id, Model $userModel, $userId) {
         // Method is currently empty
    }
}

Here is the TestCase code:

class OwnableBehaviorTest extends CakeTestCase {

    public function testIsOwned() {
        $TestModel = new Avatar();
        $TestModel->Behaviors->attach('Ownable');
        $result = $TestModel->Behaviors->Ownable->isOwnedByUser(
            $TestModel, 1, new User(), 1);
        $this->assertTrue($result);
    }
}

When I run the test I get this error:

 Call to undefined method OwnableBehavior::isOwnedByUser()

If I change the method call to isOwnedBy($TestModel, 'user', 1, new User(), 1); this works, so it looks like for some reason the mapped methods aren't working during the unit test. I have tested the mapped methods in a controller and I get no errors.

I wondered if it was down to how I was loading the behaviour into the model. I couldn't find any documentation in the cookbook on how to properly test Behaviours like there is with Components, Helpers, etc... So I just used the same techniques that the Core Behaviour tests use (Found in Cake/Test/Case/Model/Behavior/).

I did think maybe it could have been down to the fact that I am overwriting the ModelBehavior::setup() method, but I tried adding parent::setup($model, $settings) at the start of the setup method and I still get the same error. I am not overwriting any of the other ModelBehavior methods.

I guess I could just use the OwnableBehavior::isOwnedBy() method, but I'd quite like to know if I could get the mapped methods to work during a unit test.

Kenric answered 22/11, 2012 at 18:30 Comment(0)
K
2

The solution I have found is replacing this line:

$result = $TestModel->Behaviors->Ownable->isOwnedByUser(...);

with:

$result = $TestModel->isOwnedByUser(...);

So it's just a case of using it more like you would in the application, calling the behaviour method directly from the model. I don't know if this ruins the idea of a unit test and makes it more into integration testing though.

Kenric answered 23/11, 2012 at 9:47 Comment(1)
The mapped method logic is implemented by the behavior collection class that's why it doesn't work calling ->undefinedmethod on the behavior directly.Smedley

© 2022 - 2024 — McMap. All rights reserved.