我的控制器类中有以下代码:
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')) {
这样的东西。
答案 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 */
}