CakePHP 3.6控制器集成测试-未发送HTTP请求

时间:2019-01-04 20:05:27

标签: testing cakephp phpunit

我正在尝试使用CakePHP 3.6 的测试工具实施控制器集成测试。我以为可以通过对正在运行的Web服务器发出“真实”(如CURL)HTTP请求来处理此问题,但事实并非如此。下面是我正在使用的测试用例代码。

我遇到的问题:

  1. 测试用例通过某种方式设法访问控制者动作, 即使网络服务器根本没有运行(Apache停止运行且没有 开发人员网络服务器正在运行)。
  2. 运行此测试时,控制器无权访问 $_SERVER(请参见下文)以及测试用例中定义的任何$postData在控制器端都显示为空。
  3. 当我将exit;放在控制器代码中时,整个测试用例 停止,这表明控制器代码直接运行,而不是 通过HTTP请求。

问题:在测试控制器时,除了诉诸使用CURL和手动处理请求之外,如何发出“真实” HTTP请求?

很明显,我不是不了解控制器测试的完成方式,或者是做错了事。

我正在使用的测试用例:

/tests/TestCase/Controller/JobsControllerTest.php

<?php
namespace App\Test\TestCase\Controller;

use Cake\ORM\TableRegistry;
use Cake\TestSuite\IntegrationTestCase;

/**
 * App\Controller\JobsController Test Case
 */
class JobsControllerTest extends IntegrationTestCase
{

    /**
     * Test add method
     *
     * @return void
     */
    public function testAdd()
    {
        $this->useHttpServer(true);

        $this->configRequest([
            'headers' => [
                'Content-Type' => 'application/json',
                'X-Api-Key' => '8f083c8f083c8f083c8f083c'
            ]
        ]);
        $postData = [
            'user_id' => 3,
            'job_status' => 'New'
        ];
        $this->post('/jobs/add', $postData);

        $this->assertResponseSuccess();
        $jobs = TableRegistry::get('Jobs');
        $query = $jobs->find()->where(['user_id' => $postData['user_id']]);
        $this->assertEquals(1, $query->count());
    }

}

正在测试的控制器中的$_SERVER全局转储

Array
(
    [LS_COLORS] => rs=0:di=01;34 [...]
    [LANG] => en_US.UTF-8
    [HOME] => /home/tomasz
    [TERM] => screen
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
    [MAIL] => /var/mail/root
    [LOGNAME] => root
    [USER] => root
    [USERNAME] => root
    [SHELL] => /bin/bash
    [SUDO_COMMAND] => vendor/bin/phpunit --verbose
    [SUDO_USER] => tomasz
    [SUDO_UID] => 1000
    [SUDO_GID] => 1000
    [PHP_SELF] => vendor/bin/phpunit
    [SCRIPT_NAME] => vendor/bin/phpunit
    [SCRIPT_FILENAME] => vendor/bin/phpunit
    [PATH_TRANSLATED] => vendor/bin/phpunit
    [DOCUMENT_ROOT] =>
    [REQUEST_TIME_FLOAT] => 1546631688.0758
    [REQUEST_TIME] => 1546631688
    [argv] => Array
        (
            [0] => vendor/bin/phpunit
            [1] => --verbose
        )

    [argc] => 2
)

1 个答案:

答案 0 :(得分:1)

CakePHP集成测试不会发出实际的HTTP请求,它们会模拟它们,它非常快,可以进行某些模拟,检查会话内容,访问异常详细信息等,而实际上是不可能的(在使用真实的HTTP请求)。如果您确实需要发出实际请求,则应考虑使用其他实用程序,例如Codeception(专门用于验收测试)。

在使用CakePHP时,建议您不要直接访问PHP超全局变量,而应从CakePHP提供的抽象API中检索数据!破坏集成测试是这样做的原因之一。模拟的请求将收到一个请求对象,该对象已使用测试用例中的数据准备好了,这是您需要在其中查找的对象。

例如,如果您想在应用程序中(也许在控制器中)访问POST数据,则可以这样操作:

$user_id = $this->request->getData('user_id');

另请参见