cakephp 2.6控制器测试用例在重复的testAction()上调用MissingActionException - 调用

时间:2015-07-21 10:31:13

标签: unit-testing cakephp exception controller phpunit

我希望任何人都可以帮助我完成我的测试环境。

我的设置

我正在实施基于phpunit 3.7.22的单元测试,蛋糕版本为2.6.9。使用PHP 5.4.43-1和postgresql 9.1在ubuntu 12.04 LTS上运行。

我实现了控制器测试模拟蛋糕Auth Component在会话中有一个用户,因为我的测试依赖于此。我的控制器返回json结果,因为它是基于JS的前端的API。我使用生成的控制器的 testAction()调用来调用我的控制器方法。

<?php
App::uses('RequesttypesController', 'Svc.Controller');

class RequesttypesWithResultControllerTest extends ControllerTestCase
{

    public $fixtures = array(
        'app.requesttype',
        'app.user',
        'app.privilege',
        'app.groupsprivilege',
        'app.groupsuser',
        'app.groupscompany',
        'app.company',
    );

    /**
     * Mock the requesttype object so that it can return results depending on the desired outcome
     * 
     * @see CakeTestCase::setUp()
     */
    public function setUp()
    {
        parent::setUp();    
        $this->controller = $this->generate('Svc.Requesttypes', array(
            'models' => array(
                'Requesttype'
            ),
            'components' => array(
                'Auth' => array(
                    'user'
                ),
                'Session',
                'RequestHandler'
            )
        ));

        $this->controller->Auth->staticExpects($this->any())
        ->method('user')
        ->will($this->returnValue(array(
            'id' => 123,
            'username' => 'myTestUser',
            'company' => 'myTestCompany',
            'usertype_id' => '456',
        ))
        );
        $authResult = $this->controller->Auth->user();
    }

    public function tearDown()
    {
        parent::tearDown();
        unset($this->controller);
    }

    /**
     * A logged in user produces a number of requesttypes
     */
    public function testLoggedInUser()
    {
        $result = $this->testAction('/svc/requesttypes/getMyRequesttypes', array('return' => 'vars'));
        $this->assertNotEmpty($this->vars, 'Did not receive webservice response');
        $this->assertTrue(isset($this->vars['data']['code']), 'Received invalid webservice response');
        $this->assertEqual($this->vars['data']['code'], SvcAppController::RESPONSE_CODE_SUCCESS);
    }

}
?>

此测试通过且没有错误。现在我想用不同的设置来测试我的控制器动作,例如来自不同公司的具有不同usertype的用户,等等。如果我现在在 RequesttypesWithResultControllerTest -class中创建第二个测试方法,调用相同的 testAction -url,我得到 MissingActionException 说:< / p>

"Action RequesttypesController::() could not be found."

似乎testAction调用一个空的控制器动作,即使action-url作为参数传递。我尝试通过将控制器归零并再次调用 $ this-&gt; generate()来重新初始化控制器,但这也无济于事。

当然,我可以通过为每个测试创建一个自己的测试控制器来帮助自己,最终会出现在一堆重复的测试代码中,但这对我来说似乎不合适。

我是否滥用测试环境或如何解释此异常?有什么想法吗?

提前感谢分享我的头痛!

1 个答案:

答案 0 :(得分:0)

经过一些进一步的代码调试后,我们终于找到了错误。我们意外地将 /Config/routes.php 文件的最后一行的 require 语句更改为 require_once ,因为有些&#34;类已经定义了例外&#34;扔在测试环境中。

错误的routes.php:

require_once CAKE . 'Config' . DS . 'routes.php';

对于没有区别的应用程序本身,因为每个请求只需要初始化一次路由。但是在测试环境中,路由会重新初始化几次,而 require_once include则不再可能。

这就是该行看起来的样子,默认情况下是这样的:

纠正routes.php:

require CAKE . 'Config' . DS . 'routes.php';