在子目录中运行的CakePHP会在shell,web和单元测试中产生URL问题吗?

时间:2017-04-11 08:35:58

标签: php shell unit-testing cakephp cakephp-2.9

我正在使用CakePHP 2.9.7并且我正在尝试编写一个shell,它应该发送带有链接(Router::url())的邮件。该链接将指向我的CakePHP应用程序中的一个页面,该页面将发送另一个带有另一个链接的邮件。因此,我们从shell发送了一封邮件,并从应用程序中发送了一封邮件。

如果我想在shell中使用路由,那么文档可以设置App.fullBaseUrlhttps://book.cakephp.org/2.0/en/console-and-shells.html#routing-in-shells-cli。由于我不确定这是否包含完整的基本路径,我只是问及并确实知道确实如此。所以我确实将App.fullBaseUrl设置为http://example.com/my_app之类的内容。在shell中发送的邮件就像一个魅力吧! 但是,一些其他链接,例如从应用程序内发送的邮件中的邮件现在已被破坏,因为它们指向http://example.com/my_app/my_app。我认为这与我想要这些链接的完整URL有关。大多数其他链接工作正常,因为我不要求提供完整的URL。但是,如果我传递HtmlLinkHelper中的'full_base' => true选项,则会出现同样的问题。

我发现了这个:https://github.com/cakephp/cakephp/pull/1718所以我猜这会解决我的痛苦,我只需将App.fullBaseUrl设置为http://example.com,将App.base设置为/myapp。这在两种用法中都很有效。 '耶'我想并运行了所有的单元测试。他们不再工作了。

我的单元测试大量使用$this->testAction()(在ControllerTests中),所有$ this-> testAction调用现在都被破坏了。 例如:我的CartController中有一个索引动作,只能通过GET调用,所以我们编写了一个测试来通过POST调用它。这一直有效,直到我设置了App.base'。

public function testIndexPost() {
    $this->testAction(
        array(
            'controller' => 'Cart',
            'action' => 'index',
        ),
        array(
            'method' => 'POST',
            'return' => 'vars',
        )
    );
}

现在我收到错误:

  

声明类型" MissingActionException"的异常失败匹配预期的异常" MethodNotAllowedException"。消息是:"无法找到Action CartController :: Cart()。"。

堆栈追踪:

Action CartController::Cart() could not be found.
Test case: CartControllerTest(testIndexPost)

Stack trace:
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\Routing\Dispatcher.php : 193
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\Routing\Dispatcher.php : 167
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\ControllerTestCase.php : 287
ControllerTestCase::_testAction
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\ControllerTestCase.php : 199
F:\dev\xampp\htdocs\my_app\app\Test\Case\Controller\CartControllerTest.php : 83
F:\dev\xampp\htdocs\my_app\app\Test\Case\Controller\CartControllerTest.php : 83
CartControllerTest::testIndexPost
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php : 988
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php : 838
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestResult.php : 648
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestCase.php : 783
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestCase.php : 82
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php : 779
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\Framework\TestSuite.php : 749
F:\dev\xampp\htdocs\my_app\vendor\phpunit\phpunit\PHPUnit\TextUI\TestRunner.php : 350
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestRunner.php : 62
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestSuiteCommand.php : 98
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestSuiteDispatcher.php : 259
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestSuiteDispatcher.php : 96
F:\dev\xampp\htdocs\my_app\vendor\cakephp\cakephp\lib\Cake\TestSuite\CakeTestSuiteDispatcher.php : 113
F:\dev\xampp\htdocs\my_app\webroot\test.php : 104

我当然可以设置'base' => false(这使它再次起作用),但这感觉不对。我不应该因为我在我的应用程序中设置App.base而改变我的所有测试,对吧?

所以无论我做什么,我都无法通过所有CLI,Web和单元测试来使用此路由。其中一个总是搞砸了。

我做错了吗? 有没有更好的方法来处理这些事情?
这是一个错误吗?

1 个答案:

答案 0 :(得分:0)

问题似乎是在请求对象中,基本路径不会从为testAction()调用生成的网址中删除。

ControllerTestCase::_testAction()中,当将URL传递给请求对象的构造函数时,可能的基本路径不会像请求对象在CakeRequest::_url()中生成URL本身时那样被剥离,而是将URL设置为原样,然后导致错误的路由匹配。

我建议 report this as a bug ControllerTestCase::_testAction()应填充$_SERVER['REQUEST_URI'],而不是将网址传递给CakeRequest模拟。

在修复此问题之前,请尝试暂时修改ControllerTestCase::_testAction()

$_SERVER['REQUEST_URI'] = $url;
$request = $this->getMock('CakeRequest', array('_readInput'));

<强> https://github.com/cakephp/.../blob/2.9.7/lib/Cake/TestSuite/ControllerTestCase.php#L251