【发布时间】:2015-11-02 11:34:00
【问题描述】:
我正在使用一个内部框架,其中每个异常都由错误处理程序捕获并以适当的 JSON 错误响应返回,适用于 RESTFul API。
然后我有一套测试,它们是 API 测试,主要测试 API 是否返回带有预期错误代码的正确 JSON 响应。
对于每个测试,都会修改(然后恢复)全局变量以模拟不同的 HTTP 请求。我这样做是为了避免进行 cURL 测试(通过 Guzzle 或类似方法)的过载,并导致在 CLI 环境下,代码不知道服务器的 url。
<?php
// ... example, part of a base ApiTestCase class:
// Override globals (should be backed up by PHPUnit)
$_SERVER['REQUEST_METHOD'] = $request->method;
$_SERVER['QUERY_STRING'] = http_build_query($request->parameters);
$_SERVER['PATH_INFO'] = $request->path;
$_SERVER['REQUEST_URI'] = $request->path . ($_SERVER['QUERY_STRING'] ? '?' : '') . $_SERVER['QUERY_STRING'];
$_SERVER['REQUEST_TIME'] = time();
$_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
$_SERVER['HTTP_COOKIE'] = '';
// Set headers, cookies and parameters
foreach ($request->headers as $k => $v) {
$_SERVER['HTTP_' . strtoupper(str_replace('-', '_', trim($k)))] = $v;
}
if ($_SERVER['HTTP_COOKIE']) {
$GLOBALS['_COOKIE'] = http_parse_cookie($_SERVER['HTTP_COOKIE']);
} else {
$GLOBALS['_COOKIE'] = [];
}
$GLOBALS['_REQUEST'] = $request->parameters;
$responseBody = $app->start();
$response->httpCode = http_response_code();
$response->body = $responseBody ? @json_decode($responseBody) : null;
$response->headers = headers_list();
(我知道这样改变全局变量不好,框架不应该直接依赖全局变量,但我仍然要处理遗留代码。)
那么问题来了:当我尝试测试 JSON 错误响应时:PHPUnit 拦截了抛出的异常(在我开头提到的处理程序之前),因此框架没有机会将其转换为 JSON 并返回正确的响应.
我试图在 PHPUnit 手册中找到一些内容来禁用 PHPUnit 错误处理程序,但没有成功。
在这种情况下我该怎么办?谢谢
【问题讨论】:
-
请注意,您引用的大部分代码看起来应该在您的 phpUnit 测试类中的
setup()函数中。另外,请注意 phpUnit 具有在每次测试后将全局变量恢复到其原始状态的内置功能。您可能想利用它而不是重新发明轮子。 -
代码只是一个示例,但 PHPunit 确实会进行全局备份
-
@mjolnic 嗨,伙计,我在这里遇到了完全相同的问题。您找到合适的分辨率了吗?
-
我实现的唯一可行的解决方案是不依赖异常处理程序来发送错误响应,而是在应用程序的顶层捕获异常。
标签: php json api phpunit web-api-testing