我试图对我的Stripe webhook处理程序的实现进行单元测试.条带webhook数据作为POST请求正文中的原始JSON在线上传播,因此我捕获并解码数据:
public function store()
{
$input = @file_get_contents("php://input");
$request = json_decode($input);
return Json::encode($request);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试对此代码进行单元测试,但我无法弄清楚如何在单元测试中发送原始JSON数据,以便我可以使用该file_get_contents("php:input//")函数检索它.这是我尝试过的(使用PHPUnit):
protected $testRoute = 'api/stripe/webhook';
protected $validWebhookJson = <<<EOT
{
"id": "ch_14qE2r49NugaZ1RWEgerzmUI",
"object": "charge",
// and a bunch of other fields too
}
EOT;
public function testWebhookDecdoesJsonIntoObject()
{
$response = $this->call('POST', $this->testRoute, $this->validWebhookJson); // fails because `$parameters` must be an array
$response = $this->call('POST', $this->testRoute, [], [], ['CONTENT_TYPE' => 'application/json'], $this->validWebhookJson);
dd($response->getData(true)); // array(0) {} BOOOO!!! Where for to my data go?
}
Run Code Online (Sandbox Code Playgroud)
我也尝试了,curl但这会产生一个外部请求,从单元测试的角度来看,这对我没有意义.如何使用我的store方法拾取的正文中的原始JSON数据来模拟POST请求?
小智 7
您可以.但是您需要将编码的JSON作为内容(也称为请求主体)而不是参数发送.
$this->call(
'POST',
'/articles',
[],
[],
[],
$headers = [
'HTTP_CONTENT_LENGTH' => mb_strlen($payload, '8bit'),
'CONTENT_TYPE' => 'application/json',
'HTTP_ACCEPT' => 'application/json'
],
$json = json_encode(['foo' => 'bar'])
);
Run Code Online (Sandbox Code Playgroud)
那是第7个参数.
如果你看一下方法定义(在Laravel的核心中),你应该能够看到它的期望.
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
Run Code Online (Sandbox Code Playgroud)
这目前不支持尚未通过Laravel 5.1的帖子,补丁,放,删除的便利方法虽然.
编辑:我应该声明这个回答基于Laravel 5.1安装,所以如果您使用的是旧版本,它可能不是100%适用于您.
在 Laravel 5.1 中,发送 JSON 很容易,只需传递一个常规 PHP 数组,它就会自动编码。文档中的示例:
$this->post('/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
Run Code Online (Sandbox Code Playgroud)
来自文档:http://laravel.com/docs/5.1/testing#testing-json-apis