Symfony 和 PHPUnit:抛出异常但未被 setExpectedException 拦截

Symfony and PHPUnit: Exception thrown but not intercepted by setExpectedException

我为控制器编写了一个测试,该控制器将表单传递的一些数据保存在数据库中。

我编写了以下测试方法以确保如果表单为空则抛出异常:

public function testRegisterNewMerchantExceptionNoDataSubmitted()
{
    $client = static::createClient();
    $crawler = $client->request('GET', '/getstarted');

    $form = $crawler->selectButton('getStarted[submit]')->form();
    $form['getStarted[email]'] = '';

    $this->setExpectedException('DomainException');
    $client->submit($form);

    $this->assertEquals(500, $client->getResponse()->getStatusCode());

    //dump($client->getResponse());die;
}

我正在测试的方法如下:

public function endAction(Request $request)
{
    $form = $this->createForm(new GetStartedType());

    $form->handleRequest($request);

    if ($form->isValid()) {
        // Get data from form
        $data = $form->getData();
    } else {
        throw new  \DomainException('No data submitted.');
    }

    ...

我确信在测试期间也会抛出异常,因为转储 Response 对象页面是一个 500 错误报告确切的消息 "No data submitted"。 More,状态码上的assertEquals测试成功,异常正确抛出毫无疑问

但是 $this->setExpectedException() 测试没有拦截它并且 returns 测试失败。

知道为什么会这样吗?

使用 $this->setExcpectedException() 告诉 PHPUnit 期望给定的异常类型 从测试方法 中抛出,而不仅仅是在某个时候抛出该类型的异常执行期间。

当您在控制器方法中抛出异常时,Symfony 控制器会捕获 该异常并创建 500 响应。这意味着不会从测试方法中抛出异常,因此测试失败。否则你的测试看起来是合理的,所以删除 $this->setExpectedException() 应该可以解决问题并测试你想要的行为。