Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
981 views
in Technique[技术] by (71.8m points)

php - PhalconPHP MVC Micro app: Specify a request path and assert the response code

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 PhalconMvcMicro();

#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);
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...