【问题标题】:symfony WebTestCase client does not send post datasymfony WebTestCase 客户端不发送 post 数据
【发布时间】:2017-03-24 12:43:57
【问题描述】:

我目前正在为我的 symfony 应用程序编写功能测试。我使用 symfony 3 (3.1.6) 和 phpunit 5.6.1。 编辑:根据 Alvin Bunk 的要求,我的应用不是网站,它是一个仅返回 JSON 的 API。正如我在下面的两个更新中添加的那样,Symfony 测试客户端发送一个带有表单数据的正确请求对象,但应用程序的控制器接收到一个空对象。

这是我用来测试表单的代码:

public function testSaveMediaFromMediaUrl()
{
    $client = static::createClient();
    $crawler = $client->request('GET', '/form');

    $form = $crawler->selectButton('OK')->form();
    $form['mediaUrl'] = 'http://example.com';

    $client->submit($form);
    var_dump($client->getResponse()->getContent());
}

调用了我的控制器的正确操作,但是当从测试套件调用该操作时,请求对象中没有任何内容。使用普通的网络浏览器,一切正常。在控制器中,我使用$request = Request::createFromGlobals();创建请求对象

我也尝试了这段代码来发布数据,我得到了相同的结果:控制器中没有收到 POST 数据。

不使用表单直接发布请求

public function testSaveMediaFromMediaUrl()
{
    $client = static::createClient();
    $crawler = $client->request('POST', '/media', ['mediaUrl' => 'http://example.com']);

    var_dump($crawler->html());
}

在提交方法中添加数据

public function testSaveMediaFromMediaUrl()
{
    $client = static::createClient();
    $crawler = $client->request('GET', '/form');

    $form = $crawler->selectButton('OK')->form();

    $client->submit($form, ['mediaUrl' => 'http://example.com']);
    var_dump($client->getResponse()->getContent());
}

是不是我做错了什么?

编辑:

这是我在控制器操作中获得的请求对象的转储。

.object(Symfony\Component\HttpFoundation\Request)#1047 (21) {
  ["attributes"]=>
  object(Symfony\Component\HttpFoundation\ParameterBag)#1050 (1) {
    ["parameters":protected]=>
    array(0) {
    }
  }
  ["request"]=>
  object(Symfony\Component\HttpFoundation\ParameterBag)#1048 (1) {
    ["parameters":protected]=>
    array(0) {
    }
  }
  ["query"]=>
  object(Symfony\Component\HttpFoundation\ParameterBag)#1049 (1) {
    ["parameters":protected]=>
    array(0) {
    }
  }
  ["server"]=>
  object(Symfony\Component\HttpFoundation\ServerBag)#1053 (1) {
    ["parameters":protected]=>
    array(35) {[...]}
  }
  ["files"]=>
  object(Symfony\Component\HttpFoundation\FileBag)#1052 (1) {
    ["parameters":protected]=>
    array(0) {
    }
  }
  ["cookies"]=>
  object(Symfony\Component\HttpFoundation\ParameterBag)#1051 (1) {
    ["parameters":protected]=>
    array(0) {
    }
  }
  ["headers"]=>
  object(Symfony\Component\HttpFoundation\HeaderBag)#1054 (2) {
    ["headers":protected]=>
    array(0) {
    }
    ["cacheControl":protected]=>
    array(0) {
    }
  }
  ["content":protected]=>
  NULL
  ["languages":protected]=>
  NULL
  ["charsets":protected]=>
  NULL
  ["encodings":protected]=>
  NULL
  ["acceptableContentTypes":protected]=>
  NULL
  ["pathInfo":protected]=>
  NULL
  ["requestUri":protected]=>
  NULL
  ["baseUrl":protected]=>
  NULL
  ["basePath":protected]=>
  NULL
  ["method":protected]=>
  NULL
  ["format":protected]=>
  NULL
  ["session":protected]=>
  NULL
  ["locale":protected]=>
  NULL
  ["defaultLocale":protected]=>
  string(2) "en"
}

编辑-2:

这里是客户端发送的请求对象的转储(在测试用例中:var_dump($client->getRequest()->request);):

object(Symfony\Component\HttpFoundation\ParameterBag)#753 (1) {
  ["parameters":protected]=>
  array(4) {
    ["mediaUrl"]=>
    string(41) "http://example.com"
    ["url"]=>
    string(0) ""
    ["token"]=>
    string(0) ""
    ["sizes"]=>
    string(0) ""
  }
}

“测试浏览器”似乎将表单数据发送到应用程序...

【问题讨论】:

  • 您应该在帖子中提到它是一个安静的 api,并且您期望返回 JSON。 -1 未在您的帖子中显示该信息,@Matteo 给出了一个很好的答案(像往常一样),您应该对此表示赞同。如果您更新您的帖子以包含 api 信息,那么我会支持它。
  • 这并没有改变我的问题......问题是在测试客户端发送的请求和处理到应用程序内核之间的 POST 数据似乎丢失了:我的控制器收到一个空请求对象并引发错误,因此既不返回 HTML 也不返回 JSON(只是 500 错误)
  • 我编辑了帖子以添加有关应用程序的信息。 Matteo 给出的答案并没有改变任何问题......

标签: testing phpunit symfony


【解决方案1】:

问题解决了:

在我的控制器中,我使用了文档中所写的$request = Request::createFromGlobals()。我删除了这一行并添加了 $request 作为控制器操作的参数,现在请求包含测试客户端发送的 POST 数据。

我的动作现在定义如下:

public function generateAction(Request $request) {
    // no more $request = Request::createFromGlobals();
    $request->request->get('mediaUrl'); // contains data
}

【讨论】:

    【解决方案2】:

    通常对表单的 post 请求会返回重定向,如果是,请检查重定向是否是正确的响应并遵循重定向,例如:

    $client->submit($form);
    
    $this->assertTrue($client->getResponse()->isRedirect());
    $this->crawler = $client->followRedirect();
    

    希望有帮助

    编辑:

    另一种方式可能是:

    $form = $crawler->selectButton('OK')->form(array(
        'mediaUrl' => 'http://example.com')
    );
    
    $client->submit($form);
    

    【讨论】:

    • 我没有重定向,该应用程序不是网站,它只是一个 API,因此表单返回一个带有状态的 json。在form() 中传递数据不会改变任何东西...
    猜你喜欢
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 2015-01-08
    • 1970-01-01
    • 2013-02-01
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多