We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

disable model event listener during testing

I have a model that sends an email afterCreate. I'm using Codeception for testing. In order to unit test the model save, I need to disable the event model:afterCreate. Is there an elegant way to achieve this?

public function afterCreate() {
        ->send([$this->user->email => $this->user->name], 'Reset your password', 'reset', ['resetUrl' => 'reset-password/' . $this->code . '/' . $this->user->email]);

In a test for Users model:

public function testRelationToResetPasswords() {
    $userId = $this->tester->haveRecord('Myapp\Models\Users', ['name' => 'NameUsedForTesting', 'roleId' => 1, 'email' => '[email protected]']);
    $this->tester->haveRecord('Myapp\Models\ResetPasswords', ['usersId' => $userId, 'createdAt' => '0']);
    $user = Users::findFirst($userId);
    $this->assertGreaterThan(0, count($user->resetPasswords));

Mock mail service or even whole afterCreate method in model?

edited Jul '20

Moking the mail service works

$mailer = $this->make('Myapp\Plugins\Mail\Mail', ['send' => Expected::once(function ($to, $subject, $name, $params) {
    return 1;
$this->tester->addServiceToContainer('mail', $mailer);

Mocking the related model seems difficult since several methods / properties are required. A simple assign results in Table 'mock__reset_passwords_937ac673' doesn't exist in database, trying to mock setSource goes deeper down the rabbit hole.

$record = $this->construct('Myapp\Models\ResetPasswords', [], ['afterSave' => null]);
$record->assign(['usersId' => $userId, 'createdAt' => '0']);

Honestly i even think that it's better to mock only mail - this way tou make sure that is method is indeed call there. But all depends on what you want exactly to test.

You can turn off all events.

    'events' => false,
edited Nov '20

Thanks for the update and quick reply. I'll be sure to keep an eye on this thread bp credit card login