我正在尝试使用其测试工具在 CakePHP 3.6 中实现 Controller 集成测试。我假设这将通过对正在运行的网络服务器发出“真实的”(如在 CURL 中)HTTP 请求来处理,但看起来并非如此。下面是我正在使用的测试用例代码。
我遇到的问题:
- 测试用例以某种方式设法访问 Controller 操作, 即使网络服务器根本没有运行(Apache 关闭并且没有 开发网络服务器正在运行)。
- 运行此测试时, Controller 无权访问
$_SERVER
(见下文)和测试用例中定义的任何$postData
在 Controller 端显示为空。 - 当我将
exit;
放在 Controller 代码中时,整个测试用例 停止,这表明 Controller 代码直接运行,而不是 通过 HTTP 请求。
问题:除了使用 CURL 和手动处理请求之外,我如何在测试 Controller 时发出“真正的”HTTP 请求?
很明显,我要么不理解 Controller 测试是如何完成的,要么我做错了什么。
我正在使用的测试用例:
/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());
}
}
来 self 正在测试的 Controller 的 $_SERVER
global 的转储:
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
)
最佳答案
CakePHP 集成测试不发出实际的 HTTP 请求,它们模拟它们,速度非常快,允许进行某些模拟、检查 session 内容、访问异常详细信息等,各种实际上不可能的事情(在至少不容易)在使用真正的 HTTP 请求时。如果您确实需要发出实际请求,那么您应该考虑使用其他实用程序,例如 Codeception (特别是验收测试)。
使用 CakePHP 时,建议您不要直接访问 PHP superglobals,而是从 CakePHP 提供的抽象 API 中检索数据!破坏集成测试是造成这种情况的原因之一。模拟请求将收到一个请求对象,该对象已使用测试用例中的数据准备好,您需要在此处查找它。
例如,如果你想在你的应用程序中访问 POST 数据,也许在你的 Controller 中,那么你可以这样做:
$user_id = $this->request->getData('user_id');
另见
关于testing - CakePHP 3.6 Controller 集成测试 - 未发送 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54045338/