在Symfony 1.4中使用sfBrowser在功能测试中未传递内容类型

时间:2012-10-07 11:09:33

标签: symfony1 symfony-1.4 functional-testing

测试适用于POST api端点,其中数据作为JSON包含在帖子正文中。在进行发布呼叫之前,我将Content-Type设置为'application/json'。但是,当我测试格式isFormat('JSON')时,响应为空。如果我转储$request->contentType(),这也会产生空值。

为什么setHttpHeader('Content-Type','application/json')没有在功能测试期间正确设置标头的原因?

2 个答案:

答案 0 :(得分:1)

你的设置方法是正确的,但在sfBrowserBase中有这个错误:

foreach ($this->headers as $header => $value)
{
  $_SERVER['HTTP_'.strtoupper(str_replace('-', '_', $header))] = $value;
}

将content_type设置为前缀HTTP。但是在您的操作中,$ request-> getContentType()方法假设您没有前缀。

所以如果你改变了这个:

foreach ($this->headers as $header => $value)
{
  $_SERVER[strtoupper(str_replace('-', '_', $header))] = $value;
}

您可以正确使用$request->getContentType()

您可以找到更新here

答案 1 :(得分:1)

非常感谢@nicolx我可以解释更多关于正在发生的事情并提供一些进一步的指导。

正如@nicolx所指出的$request->getContentType()正在寻找没有前缀HTTP_的HTTP标头(参见sfWebRequest中的第163到173行)。但是,sfBrowserBase始终将HTTP_前缀添加到所有标头。所以添加这个mod:

foreach($this->headers as $header => $value) 
{
  if(strotolower($header) == 'content-type' || strtolower($header) == 'content_type')
  {
    $_SERVER[strtoupper(str_replace('-','_',$header))] = $value;
  } else {
    $_SERVER['HTTP_'.strtoupper(str_replace('-','_',$header))] = $value;
  }
}

这将处理在您的操作中设置和检测到的ContentType标头。如果您不包含HTTP_前缀,则其他标头将无效(例如$request->isXmlHtttpHeader()即使您在测试文件中设置此标题也会失败)。

测试方法isFormat()不测试ContentType标头,而是测试Symfony路由设置sf_format。如果我将路线设置为专门设置sf_format: json,例如

some_route:
  url: /something/to/do
  param: {module: top, action: index, sf_format: json}
然后是测试

with('request')->begin()->
   isFormat('json')->
end()->

返回true。

由于我想测试标头设置,我在sfTesterRequest中添加了一个名为isContentType()的新测试器方法。此方法的代码是:

public function isContentType($type)
{
  $this->tester->is($this->request->getContentType(),$type, sprintf('request method is "%s"',strtoupper($type)));

  return $this->getObjectToReturn();
}

调用此测试只会变为:

with('request')->begin()->
  isContentType('Application/Json')->
end()->