PHPUnit:我期望异常,它';“它被扔了,但是”$这->;“预期例外”;不';行不通

PHPUnit:我期望异常,它';“它被扔了,但是”$这->;“预期例外”;不';行不通,php,laravel,unit-testing,laravel-7,Php,Laravel,Unit Testing,Laravel 7,我想测试我的Laravel服务类中的一个特定方法。当我测试“一个好的案例”时,我所有的断言都是绿色的,并且所有内容都通过了,但是我想测试一个边缘案例,在某些情况下,当这个方法抛出异常时 当我准备数据和参数以获取此异常时,确实会抛出它,但我无法$this->expectException() 我要测试的服务有4个依赖项: 类TechMed3dSizeMeService扩展了AbstractService实现了TechMed3dSizeMeServiceInterface { 私有数据库管理器$Da

我想测试我的Laravel服务类中的一个特定方法。当我测试“一个好的案例”时,我所有的断言都是绿色的,并且所有内容都通过了,但是我想测试一个边缘案例,在某些情况下,当这个方法抛出异常时

当我准备数据和参数以获取此异常时,确实会抛出它,但我无法
$this->expectException()

我要测试的服务有4个依赖项:

类TechMed3dSizeMeService扩展了AbstractService实现了TechMed3dSizeMeServiceInterface
{
私有数据库管理器$DatabaseManager;
私有文件系统$文件系统;
私有OrderServiceInterface$orderService;
专用ScanServiceInterface$scanService;
公共函数构造(
DatabaseManager$DatabaseManager,
文件系统$FileSystem,
OrderServiceInterface$orderService,
ScanServiceInterface$scanService
) {
$this->databaseManager=$databaseManager;
$this->fileSystem=$fileSystem;
$this->orderService=$orderService;
$this->scanService=$scanService;
}
在我的测试中,在
setUp()
中,我模拟了它们:

$this->databaseManager=$this->getMockBuilder(databaseManager::class)
->disableOriginalConstructor()
->getMock();
$this->fileSystem=$this->getMockBuilder(文件系统::类)
->disableOriginalConstructor()
->getMock();
$this->orderService=$this->getMockBuilder(OrderServiceInterface::class)
->disableOriginalConstructor()
->getMock();
$this->scanService=$this->getMockBuilder(ScanServiceInterface::class)
->disableOriginalConstructor()
->getMock();
$this->techMed3dSizeMeService=新的techMed3dSizeMeService(
$this->databaseManager,
$this->fileSystem,
$this->orderService,
$this->scanService,
);
如您所见,我想要测试的服务没有被模拟,但我只是创建了它的新实例
$this->techMed3dSizeMeService=new techMed3dSizeMeService

我想测试的方法是:

公共函数getUrlScheme(int$orderId):字符串 { $order=$this->orderService->getOrderById($orderId); if(!$order instanceof order){ 抛出新ServiceResourceNotFoundException();//我想在断言中获取此异常 } if(!$this->canaccessbyownershipersufficientrole($order)){ 抛出新的ServiceAuthorizationException(); } 如果(!$order->CANBTAINSCANSFROMEXTERNALAPP){ 抛出新订单NotReadyToGetainsScansFromExternalAppException( '请求的订单未通过所需步骤获得扫描。' ); } $orderDetails=$order->orderDetailsOrders; if(!$orderDetails实例of orderDetails){ 抛出新的OrderDoesNotHaveOrderDetails( '请求的订单没有获取扫描所需的订单详细信息。' ); } 回程冲刺( “tm3d-in-3dsizeme://data?params=%s', $this->generatePayloadForUrlScheme($order,$orderDetails) ); } 好案例通过:

public function get\u url\u scheme\u为给定的\u订单\u拥有的\u假肢医生()
{
//充当
$this->actingAs($this->userProsthetist);
//创建必要的数据
$order=$this->createOrderThanCanObtainScansForUser($this->UserProthetList);
$this->createorderdetailsforder($order);
//援引
$this->orderService->expected($this->once())
->方法('getOrderById')
->威尔($this->returnValue($order));
//断言
$urlScheme=$this->techMed3dSizeMeService->getUrlScheme($order->id);
$this->assertTrue(Str::startsWith($urlScheme,'tm3d-in-3dsizeme://data?params='));
$this->assertTrue(Str::endsWith($urlScheme,'=');
}
对于坏情况,我提供不存在的订单ID,我希望得到异常:

public function get\u url\u scheme\u for\u给定的\u订单\u拥有的\u假肢医生\u其中\u订单\u不存在()
{
//充当
$this->actingAs($this->userProsthetist);
//援引
$this->orderService->expected($this->once())
->方法('getOrderById')
->will($this->returnValue(null));
//断言
$urlScheme=$this->techMed3dSizeMeService->getUrlScheme(999999);//我提供了不存在的ID
$this->expectException(ServiceResourceNotFoundException::class);//我想得到这个,我得到了,但这不起作用
}
结果:

bash-5.0# ./vendor/bin/phpunit --filter=TechMed3dSizeMeServiceTest
PHPUnit 8.5.13 by Sebastian Bergmann and contributors.

.E                                                                  2 / 2 (100%)

Time: 5.15 seconds, Memory: 28.00 MB

There was 1 error:

1) Tests\Unit\Services\TechMed3dSizeMeService\TechMed3dSizeMeServiceTest::get_url_scheme_for_given_order_owned_by_prosthetist_where_order_does_not_exist
App\Exceptions\Services\ServiceResourceNotFoundException:

/app/app/Services/TechMed3dSizeMeService/TechMed3dSizeMeService.php:45
/app/tests/Unit/Services/TechMed3dSizeMeService/TechMed3dSizeMeServiceTest.php:53

ERRORS!
Tests: 2, Assertions: 3, Errors: 1.
bash-5.0#

看起来异常是由PHPUnit引发的,但不是由PHPUnit拾取的?我做错了什么?我不应该使用
new

只需将
$this->expectException(ServiceResourceNotFoundException::class);
移动到
$urlScheme=$this->TechMed3dSizeService->getUrlScheme(99999);


天哪!你犯了我的晚安,拉斐尔!真是个愚蠢的错误,现在一切都变得轻而易举了!
public function get_url_scheme_for_given_order_owned_by_prosthetist_where_order_does_not_exist()
{
    // Act as
    $this->actingAs($this->userProsthetist);

    // Invoke
    $this->orderService->expects($this->once())
        ->method('getOrderById')
        ->will($this->returnValue(null));


    // Assert
    $this->expectException(ServiceResourceNotFoundException::class);
    $urlScheme = $this->techMed3dSizeMeService->getUrlScheme(999999); // I provide non existing ID
}