如何到达异常块

How to reach the exception block

所以我在摆弄 symfony 路由器组件,并创建了一个小包装器。

出现的一件事是我如何获得在单元测试中抛出 500 分的请求?有问题的方法是:

public function processRoutes(Request $request) {

    try {
        $request->attributes->add($this->_matcher->match($request->getPathInfo()));
        return call_user_func_array($request->attributes->get('callback'), array($request));
    } catch (ResourceNotFoundException $e) {
        return new RedirectResponse('/404', 302);
    } catch (Exception $e) {
        return new RedirectResponse('/500', 302);
    }
}

有问题的测试是:

public function testFiveHundred() {
    $router = new Router();

    $router->get('/foo/{bar}', 'foo', function($request){
        return 'hello ' . $request->attributes->get('bar');
    });

    $response = $router->processRoutes(Request::create('/foo/bar', 'GET'));

    $this->assertEquals(500, $response->getStatusCode());
}

现在测试将失败,因为我们已定义并且状态代码将为 200。我可以对我创建的 Request 对象做一些特别的事情,让它抛出 500 吗?

我想你有几个可以玩的选项:

  1. 确定特定路径将始终抛出异常。
    这将迫使您对代码进行一些更改。


public function processRoutes(Request $request) {
    ...
        if ($request->getRequestUri() == '/path/that/throws/exception') {
            throw  Exception('Forced to throw exception by URL');
        }
    ...
}

public function testFiveHundred() {
    ...
    $response = $router->processRoutes(Request::create('/path/that/throws/exception', 'GET'));
    ...
}
  1. 制作一个 DummyRequest 对象来扩展您的原始请求 class 并确保该对象会引发异常(例如 - 您肯定知道您使用 getPathInfo() ,所以你可以使用这个)。


class DummyRequest extends Request {

    public function getPathInfo() {
        throw new Exception('This dummy request object should only throw an exception so we can test our routes for problems');
    }

}

public function testFiveHundred() {
    ...
    $dummyRequest = new DummyRequest();
    $response = $router->processRoutes($dummyRequest);
    ...
}

由于我们 $dummyRequest 的函数 getRequestUri 抛出异常,您对 $router->processRoutes 的调用将让我们的虚拟对象抛出该异常。

This is a general idea, you would probably need to play a bit with the namespaces and the functions there (I didn't test it, however this should work).