问题
I've followed the unit testing tutorial and modified it to test a HTTP request to Micro MVC app, based on this post. I can successfully validate the output string, however I'm not sure how to assert the response status code or change the request path.
index.php
<?php
$app = new \Phalcon\Mvc\Micro();
#Default handler for 404
$app->notFound(function () use ($app) {
$app->response->setStatusCode(404, "Not Found")->sendHeaders();
});
$app->post('/api/robots', function() use ($app) {
//Parse JSON as an object
$robot = $app->request->getJsonRawBody();
//Build the response
$app->response->setJsonContent($robot);
return $app->response;
});
$app->get('/', function() {
echo 'Hello';
});
$app->handle();
tests/UnitTest.php
class MvcMicroUnitTest extends \UnitTestCase {
public function testNotFound() {
$path = '/invalid';
$mockRequest = $this->getMock("\\Phalcon\\Http\\Request");
//TODO: Set an invalid URL $path in the mock
$this->di->set('request', $mockRequest, true);
include("../index.php");
//TODO: Assert status is 404
$this->expectOutputString('');
}
public function testPostRobot() {
$rawJson = '{"name":"C-3PO","type":"droid","year":1977}';
$path = '/api/robots';
$mockRequest = $this->getMock("\\Phalcon\\Http\\Request", array(
"getJsonRawBody"));
$mockRequest->expects($this->any())
->method("getRawBody")
->will($this->returnValue($rawJson));
//TODO: Set the $path in the mock
$this->di->set('request', $mockRequest, true);
include("../index.php");
//TODO: Assert status is 200
$this->expectOutputString($rawJson);
}
}
回答1:
Good news and bad news. Good: as far as you use the standard dispatching principle you will have a response, that would contain the information you need. Small trick – when status is success the header is set to false
.
/**
* @param $expected
* @throws ExpectationFailedException
* @return $this
*/
protected function assertResponseCode($expected)
{
$actual = $this->di->getResponse()->getHeaders()->get('Status');
if ($actual !== false && $expected !== 200 && !preg_match(sprintf('/^%s/', $expected), $actual)) {
throw new ExpectationFailedException(sprintf('Failed asserting that response code is "%s".', $expected));
}
$this->assertTrue(true);
return $this;
}
Bad: you are doing it the wrong way. This is area of functional / acceptance testing and there is a fabulous framework called Behat. You should do your own research, but essentially, while PHPUnit is great at testing more or less independent blocks of functionality it sucks at testing bigger things like full request execution. Later you will start experiencing issues with session errors, misconfigured environment, etc., all because each request is supposed to be executed in it's own separate space and you force it into doing the opposite. Behat on the other hand works in a very different way, where for each scenario (post robot, view non-existing page), it sends a fresh request to the server and checks the result. It is mostly used for final testing of everything working together by making assertions on the final result (response object / html / json).
来源:https://stackoverflow.com/questions/25771821/phalconphp-mvc-micro-app-specify-a-request-path-and-assert-the-response-code