测试方法是从 AJAX 请求还是从 PhpUnit 调用的

Test if method is called from and AJAX request or from PhpUnit

我已经开始对当前项目实施单元测试。

虽然目前所有单元测试都通过了,但为了方便起见,我对 jsonResponse 方法进行了更改,以同时发送 json headers。这有助于我在 Chrome 控制台中将 json 响应视为一棵树。

现在单元测试由于

而失败

Cannot modify header information - headers already sent by
(output started at [fullPath]/phpunit/src/Util/Printer.php:134)

深入挖掘,我发现可以通过在 docBlocks 中添加 @runInSeparateProcess 来解决这个问题。

但这只会导致:

PHP Fatal error: Class 'PHPUnit_Util_Configuration' not found in - on line 365
PHP Stack trace:
PHP 1. {main}() -:0

这是我的 json 方法之一(在通过 AJAX 请求调用的几个方法的末尾调用):

/**
 * Helper function to print a json encoded success message back to the frontend.
 *
 * @param array $returnData
 *
 * @return bool
 *
 * @runInSeparateProcess
 */
public function returnJsonSuccess($returnData = [])
{
    header('Content-Type: application/json');
    echo json_encode(
        [
            "success" => true,
            "data"    => $returnData,
        ]
    );
    return true;
}

那么,切入正题,我怎样才能让它正常工作?

我的一个选择是检测该方法是否从单元测试中调用,并且只有在正常调用时才有条件地发送 headers。我认为最简单的方法是在 bootstrap 文件中定义一个环境变量或常量,并在我的 BaseController.

中检查它

是否有更简洁的方法让我的单元测试再次工作,同时保持 json headers 已发送?

在我看来,您有两种可能的解决方案:

  1. 在您的 phpunit bootstrap 文件中设置环境密钥并检查该服务器密钥是否存在
  2. 在您的 class 中使用一个变量,该变量将在您的 setUp 方法中禁用

希望对您有所帮助

我自己解决了:

/**
 * Helper function to print a json encoded success message back to extJs.
 *
 * @param array $returnData
 *
 * @return bool
 */
public function returnJsonSuccess($returnData = [])
{
    $request = $this->getRequest();
    if ($request && $request->isXmlHttpRequest()) {
        header('Content-Type: application/json');
    }
    echo json_encode(
        [
            "success" => true,
            "data"    => $returnData,
        ]
    );
    return true;
}

ZendFramework,使用 Request class,可以检测调用是否来自 AJAX 请求。这样,如果有 AJAX 请求,我只会发送 headers。