如何测试苗条中间件(phpunit)

时间:2016-09-14 09:52:32

标签: unit-testing redirect phpunit response slim

我创建了一个中间件,它只应该将用户重定向到其他网站(通过参数重定向在请求URL中给出)

class Middleware
{
    public function __invoke($request, $response, $next)
    {
        // Call next middleware or app
        $response = $next($request, $response);

        $redirectUrl = //get redirect url

        return $response->withStatus(200)->withHeader('Location', $redirectUrl);
    }
}

我已经测试过了,Redirect工作正常。所以我来到那个点写单元测试。我失败了...这是我的尝试:

class MiddlewareTest extends \PHPUnit_Framework_TestCase
{
    public $request = array(...); //inserted needed properties

    public function testInvoke(String $url) {
        $next = function () : bool
        {
            return true;
        }; //empty function
        $request['request']['scriptUri'] = "/parameterStuff&redirect=" . $url; //overwrite the Uri with provided Url
        $redirect = new Middleware($request, array(), $next);

        //just to test if result of response still empty
        $iCount = count((array)$redirect);
        $this->assertEquals(0, $iCount);

    }

    public function invokeProvider() : array
    {
        return array(
            array('http://example.com')
        );
    }
}

这个测试是成功的,但是它不应该......这个函数的返回应该是一个有效的响应。我在浏览器中对此进行了测试并回复了返回。它有一个值,它是预期标题的正确响应。我在Unit-Test中收到的返回值是一个空对象。

我将关于响应对象的Slim Documentation改为红色,并且它是sais:

  

此方法返回具有新标头值的Response对象的副本。   所以我绝对应该收到一些东西。我还试图返回一份回复:

$copyresponse = response->withStatus(200)->withHeader('Location', $redirectUrl);
return $copyresponse;

这不行。任何想法可能导致我的问题以及如何解决它?

(我想测试是否在响应中正确设置了重定向网址,以确保重定向能够正常工作)

1 个答案:

答案 0 :(得分:0)

您必须模拟请求并检查Location标头是否已正确设置,其长度是否为1,状态代码是否为200。我写了some different middleware,我使用了这种方法。

class LocationTest extends \PHPUnit_Framework_TestCase
{
    /**
     * PSR7 request object.
     *
     * @var Psr\Http\Message\RequestInterface
     */
    protected $request;

    /**
     * PSR7 response object.
     *
     * @var Psr\Http\Message\ResponseInterface
     */
    protected $response;

    protected $headers;

    protected $serverParams;

    protected $body;

    /**
     * Run before each test.
     */
    public function setUp()
    {
        $uri = Uri::createFromString('https://example.com:443/foo/bar');
        $this->headers = new Headers();
        $this->headers->set('REMOTE_ADDR', '127.0.0.1');
        $this->cookies = [];
        $env = Environment::mock();
        $this->serverParams = $env->all();
        $this->body = new Body(fopen('php://temp', 'r+'));
        $this->response = new Response();
        $this->request = new Request('GET', $uri, $this->headers, $this->cookies, $this->serverParams, $this->body);
    }

    /**
     * @dataProvider locationProvider
     */
    public function testLocation($url)
    {
        $options = array(
          'ip' => '192.*',
        );
        $mw = new RestrictRoute($options);

        $next = function ($req, $res) {
            return $res;
        };
        $uri = Uri::createFromString('https://example.com:443/foo/bar?redirect=' . $url);
        $this->request = new Request('GET', $uri, $this->headers, $this->cookies, $this->serverParams, $this->body);
        $redirect = $mw($this->request, $this->response, $next);
        $location = $redirect->getHeader('Location');
        $this->assertEquals($redirect->getStatusCode(), 200);
        $this->assertEquals(count($location), 1);
        $this->assertEquals($location[0], $url);
    }

    public function locationProvider(){
      return [
        ['http://www.google.it'],
        ['http://stackoverflow.com/'],
      ];
    }
}