使用PHPUnit模拟Slim框架的POST请求端点

6

我想使用PHPUnit测试我的Slim应用程序的端点。 我无法模拟POST请求,因为请求体始终为空。

  • 我尝试了这里描述的方法:Slim Framework endpoint unit testing。(添加环境变量slim-input
  • 我尝试直接写入php://input,但是我发现php://input是只读的(通过艰辛的方式)

环境的仿真工作正常,例如REQUEST_URI始终如预期。 我发现请求的正文在Slim\Http\RequestBody中从php://input读取。

注:

  • 我希望避免直接调用控制器方法,以便我可以测试所有内容,包括端点。
  • 我希望避免使用guzzle,因为它会发送实际请求。 我不想在测试应用程序时运行服务器。

到目前为止,我的测试代码:

//inherits from Slim/App
$this->app = new SyncApiApp(); 

// write json to //temp, does not work
$tmp_handle = fopen('php://temp', 'w+');
fwrite($tmp_handle, $json);
rewind($tmp_handle);
fclose($tmp_handle);

//override environment
$this->app->container["environment"] =
    Environment::mock(
        [
            'REQUEST_METHOD' => 'POST',
            'REQUEST_URI' => '/1.0/' . $relativeLink,
            'slim.input' => $json,
            'SERVER_NAME' => 'localhost',
            'CONTENT_TYPE' => 'application/json;charset=utf8'
        ]
    );

 //run the application
 $response = $this->app->run();
 //result: the correct endpoint is reached, but $request->getBody() is empty

整个项目(请注意,我在stackoverflow上简化了代码):https://github.com/famoser/SyncApi/blob/master/Famoser.SyncApi.Webpage/tests/Famoser/SyncApi/Tests/ 注2: 我在slimframework论坛上提出了问题,链接如下: http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973。我会让stackoverflow和discourse.slimframework保持同步。
注3: 目前我有一个关于此功能的pull request: https://github.com/slimphp/Slim/pull/2086

1
为什么不直接使用 Guzzle 发送 POST 请求呢? - Tebe
我已经更改了我的问题标题。我想使用PHPUnit来测试端点。 - Florian Moser
你能给我们提供一个示例端点和测试吗?我不确定你提供的代码想要做什么。 - nerdlyist
我已经添加了项目链接和我的测试代码。由于该项目相当大,我没有指定端点代码。然而,在我的调试环境中,我可以验证$request->getBody()为空。 - Florian Moser
我已经从使用此API的应用程序中进行了POST请求,$request->getBody()不为空。 - Florian Moser
1个回答

5

http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/7上有帮助,解决方法是从头开始创建Request,并编写请求正文。

//setup environment vals to create request
$env = Environment::mock();
$uri = Uri::createFromString('/1.0/' . $relativeLink);
$headers = Headers::createFromEnvironment($env);
$cookies = [];
$serverParams = $env->all();
$body = new RequestBody();
$uploadedFiles = UploadedFile::createFromEnvironment($env);
$request = new Request('POST', $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles);

//write request data
$request->write(json_encode([ 'key' => 'val' ]));
$request->getBody()->rewind();
//set method & content type
$request = $request->withHeader('Content-Type', 'application/json');
$request = $request->withMethod('POST');

//execute request
$app = new App();
$resOut = $app($request, new Response());
$resOut->getBody()->rewind();

$this->assertEquals('full response text', $resOut->getBody()->getContents());

原始的博客文章可以在http://glenneggleton.com/page/slim-unit-testing找到,它有助于回答问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接