Laravel Nova Lens存在性PHPUnit测试报错:lensExists方法不存在
Laravel Nova Lens 存在性测试问题解决思路
问题描述
需要编写PHPUnit测试确认Laravel Nova中的LotExpiry Lens是否存在,作为后续测试用户访问权限的基础。当前测试代码尝试调用Nova::lensExists()方法,但执行测试时抛出错误:
<?php namespace Tests\Unit; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Laravel\Nova\Nova; use PHPUnit\Framework\TestCase; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions; class LotExpiryLensTest extends TestCase { use RefreshDatabase; protected function setUp(): void { parent::setUp(); } /** @test */ public function a_lot_expiry_lens_exists() { $this->assertTrue(Nova::lensExists('LotExpiry')); } }
执行命令./vendor/bin/phpunit --verbose --testdox tests后收到错误:
Lot Expiry Lens (Tests\Unit\LotExpiryLens) ✘ A lot expiry lens exists 5 ms ┐ ├ BadMethodCallException: Method lensExists does not exist. │ ╵ /home/vagrant/code/vendor/laravel/nova/src/Nova.php:1261 ╵ /home/vagrant/code/tests/Unit/LotExpiryLensTest.php:29 ┴
尝试resourceExists()方法也得到相同错误。
解决思路
Laravel Nova的Nova类并没有提供lensExists()方法,需要通过以下两种方式替代:
方法一:验证Lens类存在且已注册到对应Resource
这种方式同时验证Lens类本身存在,并且已经被正确注册到关联的Nova Resource中(只有注册后,Nova才会在界面展示该Lens):
<?php namespace Tests\Unit; use App\Nova\Lenses\LotExpiry; use App\Nova\Product; // 替换为实际关联LotExpiry的Resource类 use Illuminate\Foundation\Testing\RefreshDatabase; use PHPUnit\Framework\TestCase; class LotExpiryLensTest extends TestCase { use RefreshDatabase; /** @test */ public function lot_expiry_lens_exists_and_is_registered() { // 1. 检查Lens类是否存在 $this->assertTrue(class_exists(LotExpiry::class)); // 2. 检查对应Resource是否注册了该Lens $resource = new Product(); $registeredLenses = collect($resource->lenses(request()))->pluck('class'); $this->assertContains(LotExpiry::class, $registeredLenses); } }
方法二:通过Nova的resolveLens方法验证
利用Nova内置的resolveLens()方法,该方法会尝试根据名称解析Lens,不存在则抛出LensNotFoundException,通过捕获异常判断Lens是否可被Nova识别:
<?php namespace Tests\Unit; use Laravel\Nova\Exceptions\LensNotFoundException; use Laravel\Nova\Nova; use Illuminate\Foundation\Testing\RefreshDatabase; use PHPUnit\Framework\TestCase; class LotExpiryLensTest extends TestCase { use RefreshDatabase; /** @test */ public function lot_expiry_lens_can_be_resolved_by_nova() { try { Nova::resolveLens('LotExpiry'); $this->assertTrue(true); } catch (LensNotFoundException $e) { $this->fail("LotExpiry Lens无法被Nova解析:{$e->getMessage()}"); } } }
后续权限测试提示
完成Lens存在性测试后,若要测试用户是否有权限访问该Lens,可以模拟用户登录,访问对应的Lens路由,通过返回状态码判断权限:
- 状态码
200表示用户有权限访问 - 状态码
403表示用户无权限访问
内容的提问来源于stack exchange,提问作者Asa LeHolland
相关产品推荐
相关产品推荐

