如何故意使$ model-> save()失败以进行测试?

时间:2018-08-27 12:36:27

标签: yii2 codeception

我的控制器类中有以下代码:

public function actionRevoke($id) {
    $model = Token::findById($id);
    $model->revoked_at = new Expression('NOW()');
    if ($model->save()) {
        Yii::$app->getSession()->setFlash('success', 'Revoked token');
    } else {
        Yii::$app->getSession()->setFlash('danger', 'Failed to revoke token');
    }
    return $this->render('revoke',['model' => $this]);
}

现在,运行具有代码覆盖率的CodeCeption,它告诉我,setFlash('danger',...)的部分未被测试覆盖。

如何故意使$model->save()无法触发setFlash('danger,...)指令?

如果我不需要为我的Controller专门添加额外的代码来进行测试,我真的很喜欢。因此,尤其是,如果可以避免的话,我不要像if ($model->save() && !defined('TEST_FAIL_SAVE')) {这样的东西。

1 个答案:

答案 0 :(得分:0)

该解决方案(如@scaisEdge所建议)使用验证规则。我添加了一条规则,该规则将$model->token的长度严格限制为36。我的应用程序仅生成长度为36个字符的令牌。在我的测试中,我使用update数据库中的行来显示abcd作为令牌,显然少于36个字符。 由于此更改是在数据库级别进行的,因此会绕过Yii的验证并提交给数据库。

在测试期间,它会更改$model->revoked_at的值并尝试保存它,但是由于$model->token太短而使验证失败。

这是测试功能中的相关部分,控制器的代码未更改:

public function revokeToken(FunctionalTester $I){
    // login and navigation to relevant page
    Yii::$app->db->createCommand()->update('tokens',['token' => 'abcd'],['id' => 201 ])->execute();
    $I->click('a.btn.btn-danger');             /* click the 'revoke' button, this triggers actionRevoke($id) */
    $I->seeFlash('Failed to revoke token');    /* expect a flash message */
}