在AppController中单元测试beforeFilter()和beforeRender()的正确方法


Proper way to unit test beforeFilter() and beforeRender() in AppController

我正在为一个使用CakePHP 2.3的新站点编写单元测试。一切都很顺利,除了一件事。我想测试beforeFilter()和beforeRender()函数。通过创建一个模拟对象

,我可以很容易地进行测试
$app_controller_mock = $this->generate(
    'App',
    array(
        'components' => array(
            'Session'
        )
    )
);
$app_controller_mock->beforeFilter();

这将运行函数,但它不会给我有用的东西,如$this->vars, $this->content等。在这个特定的函数,这是好的,但在我的beforeRender()我手动设置一个viewVar,我想检查在我的测试用例。

$app_controller_mock->beforeRender();
$this->assertNotNull($this->vars['controller_name'], "'controller_name' viewVar is null");
当我执行上述操作时,我得到以下错误:
'controller_name' viewVar is null
Failed asserting that null is not null.

做这件事的"正确"方法是什么?

我通常做的是调度一个完整的请求,这确保beforeFilterbeforeRender的所有集成组件都存在。

有时,一个虚拟控制器是有用的:

App::uses('ControllerTestCase', 'TestSuite');
App::uses('AppController', 'Controller');
class MockFiltersController extends AppController {
    public $controllerVar = 'something';
    public function action($var1 = null) {
        // can be helpful to set other vars, or
        // set something on the controller
        $this->controllerVar = $var1;
        $this->set(compact($var1));
    }
}
class AppControllerTest extends ControllerTestCase {
    public function testBeforeRender() {
        $this->testAction('/mock_filters/action/test', array(
            'method' => 'GET'
        ));
        // ensure view vars are set
        $this->assertEquals('test', $this->vars['var1']);
        // other assertions for beforeRender items
    }
}

然后重复beforeFilter,必要时使用generate()

$this->varscontentview等变量仅在使用ControllerTestCase::testAction运行集成测试时设置。

使用这个方法对我来说似乎是有效的,因为我可以检查在控制器本身上改变的变量,与各种组件的集成,当然还有正在设置的视图变量。