ddinchev
ddinchev

Reputation: 34673

Yii2 testing when using blameable behavior

I have a model using Blameable behavior:

class Vehicle extends ActiveRecord 
{
    // ...
    public function behaviors()
    {
        return [
            'blameable' => [
                'class' => BlameableBehavior::className(),
                'createdByAttribute' => 'UserID',
                'updatedByAttribute' => null,
            ]
        ];
    }
    // ...
}

The problem is when I try to save an instance of Vehicle for testing with specific UserID, Blameable will override that with null (as no user is set to be the current logged in) and save of the model would fail.

This snipped illustrates how I've been solving this so far:

$owner = $this->createUser(); // creates user with fake data
Yii::$app->user->setIdentity($owner);
$vehicle = $this->createVehicle(); // creates vehicle and relies that the $owner->UserID will be set when vehicle is being saved

However I don't like it because it's not obvious why the user identity is being set before hand. Is there a way to disable the Blameable behavior in testing?

Upvotes: 6

Views: 1670

Answers (2)

Jairus
Jairus

Reputation: 846

Detaching the behavior wont solve the issue for those using 'value' => Yii::$app->user->identity->username since calling new Model will still throw an error.

Instead you can use the _before method to set the identity for all the tests.

unit test


use app\models\User; // your user class


class SupplierTest extends \Codeception\Test\Unit
{
    protected function _before()
    {
        // Required for model blameable behavior using Yii@.
        $owner = new User(); 
        $owner->username = 'tester';
        $owner->auth_key = '123456';
        $owner->password_hash = '123456';
        $owner->email = '[email protected]';
        $owner->save();
        Yii::$app->user->setIdentity($owner);   
    }

    public function testCreateRecord() {
        $rec = new Supplier();
        $rec->supplier = "Supplier ABC";
        $rec->smr_number = "123456";
        $rec->validate();
        Debug::debug($rec->getErrors());
        $this->assertTrue($rec->save());
    }

various model behaviors

    public function behaviors()
    {
        return [
            [
                'class' => \yii\behaviors\BlameableBehavior::className(),
                'value' => Yii::$app->user->identity->username,
            ],
            [
                'class' => \yii\behaviors\TimestampBehavior::className(),
                'value' => new \yii\db\Expression('NOW()'),
            ],
            [
                'class' => 'sammaye\audittrail\LoggableBehavior',
                'userAttribute' => 'updated_by', //blameable attribute of the current model.
                'ignored' => ['updated_by', 'updated_at'], // This ignores fields from a selection of all fields, not needed with allowed
            ],
        ];
    }

Upvotes: 0

SilverFire
SilverFire

Reputation: 1592

Just detach the BlamableBehavior in your createVehicle() method as follows:

public function createVehile()
{
    $vehicle = new Vehicle();
    $vehicle->detachBehavior('blameable');
    // ...
}

Upvotes: 3

Related Questions