php - PHPUnit:我期待异常,它被抛出但“$this->expectException”不起作用
问题描述
我想从我的 Laravel 服务类中测试一个特定的方法。当我测试“一个好案例”时,我的所有断言都是绿色的并且一切都通过了,但是我想在某些情况下这个方法抛出异常时测试一个边缘案例。
当我准备我的数据和参数以获取此异常时,确实它被抛出但我不能$this->expectException()
。
我要测试的服务有 4 个依赖项:
class TechMed3dSizeMeService extends AbstractService implements TechMed3dSizeMeServiceInterface
{
private DatabaseManager $databaseManager;
private FileSystem $fileSystem;
private OrderServiceInterface $orderService;
private ScanServiceInterface $scanService;
public function __construct(
DatabaseManager $databaseManager,
FileSystem $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(FileSystem::class)
->disableOriginalConstructor()
->getMock();
$this->orderService = $this->getMockBuilder(OrderServiceInterface::class)
->disableOriginalConstructor()
->getMock();
$this->scanService = $this->getMockBuilder(ScanServiceInterface::class)
->disableOriginalConstructor()
->getMock();
$this->techMed3dSizeMeService = new TechMed3dSizeMeService(
$this->databaseManager,
$this->fileSystem,
$this->orderService,
$this->scanService,
);
如您所见,我要测试的服务没有被模拟,我只是创建了它的新实例$this->techMed3dSizeMeService = new TechMed3dSizeMeService
。
我要测试的方法是:
public function getUrlScheme(int $orderId): string
{
$order = $this->orderService->getOrderById($orderId);
if (!$order instanceof Order) {
throw new ServiceResourceNotFoundException(); // I want to get this exception in assertion
}
if (!$this->canAccessByOwnershipOrSufficientRole($order)) {
throw new ServiceAuthorizationException();
}
if (!$order->canObtainScansFromExternalApp) {
throw new OrderNotReadyToObtainScansFromExternalAppException(
'Requested Order did not pass through required steps to obtain scans.'
);
}
$orderDetails = $order->orderDetailsOrders;
if (!$orderDetails instanceof OrderDetails) {
throw new OrderDoesNotHaveOrderDetails(
'Requested Order does not have Order Details necessary to obtain scans.'
);
}
return sprintf(
'tm3d-in-3dsizeme://data?params=%s',
$this->generatePayloadForUrlScheme($order, $orderDetails)
);
}
好案例通过:
public function get_url_scheme_for_given_order_owned_by_prosthetist()
{
// Act as
$this->actingAs($this->userProsthetist);
// Create necessary data
$order = $this->createOrderThanCanObtainScansForUser($this->userProsthetist);
$this->createOrderDetailsForOrder($order);
// Invoke
$this->orderService->expects($this->once())
->method('getOrderById')
->will($this->returnValue($order));
// Assert
$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_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
$urlScheme = $this->techMed3dSizeMeService->getUrlScheme(999999); // I provide non existing ID
$this->expectException(ServiceResourceNotFoundException::class); // I want to get this and I get but this doesn't work
}
结果:
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 没有选择?我究竟做错了什么?我不应该使用new
?
解决方案
只是移动$this->expectException(ServiceResourceNotFoundException::class);
到之前 $urlScheme = $this->techMed3dSizeMeService->getUrlScheme(999999);
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
}
推荐阅读
- python - pip install windows 后无法使用 coockiecutter 命令
- r - 匹配字符前的数字或第一个字母 - 正则表达式
- static-analysis - 如何打包 .NET 应用程序以进行验证码扫描
- c++ - 问:如何在 main 中使用 std::vector 调用模板类?
- vim - 光标一直自动跳到下一行
- snowflake-cloud-data-platform - 从外部阶段加载数据 - 将阶段名称传递给参数
- amazon-web-services - 在 Lambda 中将 AWS 弹性 IP 分配给 EC2 实例
- python - 将 Outlook 电子邮件拖放到 Python 脚本中
- java - Spring Boot BigQuery 数据源连接
- python - 将数据框的内容复制到具有相同行和列的另一个数据框