使用 Laravel 5.2 的 PHPUnit 未找到自定义异常
Posted
技术标签:
【中文标题】使用 Laravel 5.2 的 PHPUnit 未找到自定义异常【英文标题】:Custom exception not found by PHPUnit with Laravel 5.2 【发布时间】:2016-09-23 12:36:33 【问题描述】:我正在尝试抛出一个新的自定义异常,并编写测试以确保它确实被抛出。我在以下位置创建了一个新异常 App\Exceptions\AgreementsNotSignedException.php
<?php
namespace App\Exceptions;
class AgreementsNotSignedException extends \Exception
我的订单的“结帐”方法如下所示:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Exceptions\AgreementsNotSignedException as AgreementsNotSignedException;
class Order extends Model
public function checkout()
throw new AgreementsNotSignedException("User must agree to all agreements prior to checkout.");
我失败的基本测试如下所示:
<?php
use App\Order;
use App\Exceptions\AgreementsNotSignedException;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class OrderTest extends TestCase
/** @test * */
function it_does_not_allow_the_user_to_checkout_with_unsigned_contracts()
$exceptionClass = get_class(new App\Exceptions\AgreementsNotSignedException());
$this->setExpectedException(
$exceptionClass, 'User must agree to all agreements prior to checkout.'
);
try
$this->order->checkout();
catch (App\Exceptions\AgreementsNotSignedException $exception)
$this->assertNotEquals($this->order->status, "completed");
吐出的消息是“断言“App\Exceptions\AgreementsNotSignedException”类型的异常被抛出失败。但是我可以通过 xdebug 验证确实捕获了异常。正如 Jeff 在 cmets 中所说,这似乎是一个 FQN 问题,因为这样做会使测试通过:
/** @test * */
function it_does_not_allow_the_user_to_checkout_with_unsigned_contracts()
$exceptionClass = get_class(new App\Exceptions\AgreementsNotSignedException());
$this->setExpectedException(
$exceptionClass, 'User must agree to all agreements prior to checkout.'
);
throw new App\Exceptions\AgreementsNotSignedException('User must agree to all agreements prior to checkout.');
我会通过更改 FQN 继续探索,但任何指导都会很棒。
【问题讨论】:
需要指定预期异常的全限定命名空间,如this question OrderTest类中的$this->order是如何定义的? 这是一个受保护的变量,在 setup 方法中被赋值(图中未显示)。 order 变量很好,我可以在调用 checkout 之前使用调试器验证它的状态。 【参考方案1】:刚遇到同样的问题,找到了解决办法,根据源码,PhpUnit的$this->setExpectedException()
方法已弃用。
*
* @since Method available since Release 3.2.0
* @deprecated Method deprecated since Release 5.2.0
*/
public function setExpectedException($exception, $message = '', $code = null)
我改用了 $this->expectException(MyCustomException::class)
,它成功了。
【讨论】:
【参考方案2】:尝试:
$this->setExpectedException(
'App\Exceptions\AgreementsNotSignedException, 'User must agree to all agreements prior to checkout.'
);
而不是这个:
$exceptionClass = get_class(new App\Exceptions\AgreementsNotSignedException());
$this->setExpectedException(
$exceptionClass, 'User must agree to all agreements prior to checkout.'
);
【讨论】:
不幸的是同样的错误。我首先尝试过这个,然后使用 get_class 方法,希望它能更好地限定事情。我已经设法使用 assertThat 和 PHPUnit_Framework_Constraint_Exception 让这个测试工作。以上是关于使用 Laravel 5.2 的 PHPUnit 未找到自定义异常的主要内容,如果未能解决你的问题,请参考以下文章
使用 Laravel 5.2 的 PHPUnit 未找到自定义异常
Laravel 5.2 PHPUnit JSON Api 请求正文未设置