如何使用PHPUnit测试Laravel Auth服务提供者的viaRequest方法逻辑
错误原因
Laravel 的 Application 容器实现了ArrayAccess接口,支持通过$app['auth']这种数组语法获取容器内的服务。你只单纯 Mock 了Application::class,没有模拟数组访问的响应逻辑,因此代码运行到$this->app['auth']时就会抛出「不能将 Mock 对象作为数组使用」的错误。
正确测试实现
你需要同步 Mock 容器中的 Auth 管理器,同时捕获viaRequest传入的自定义验证闭包,单独对闭包逻辑做测试,完整的测试代码如下:
class AuthServiceProviderTest extends TestCase { protected $app_mock; protected $auth_mock; protected $provider; // 存储viaRequest传入的验证闭包 protected $authCallback; public function setUp(): void { $this->setUpMocks(); $this->provider = new AuthServiceProvider($this->app_mock); parent::setUp(); } private function setUpMocks(){ $this->auth_mock = \Mockery::mock(\Illuminate\Auth\AuthManager::class); // 模拟Auth的viaRequest方法,捕获传入的回调 $this->auth_mock->shouldReceive('viaRequest') ->once() ->with('api', \Mockery::type('callable')) ->andReturnUsing(function ($driver, $callback) { $this->authCallback = $callback; }); $this->app_mock = \Mockery::mock(Application::class)->makePartial(); // 模拟数组访问,返回Auth的Mock对象 $this->app_mock->shouldReceive('offsetGet') ->with('auth') ->andReturn($this->auth_mock); } // 测试服务提供者初始化 public function testIfProviderIsConstructed(){ $this->assertInstanceOf(AuthServiceProvider::class, $this->provider); } // 测试viaRequest被正常调用 public function testIfviaRequestIsCalled(){ $this->provider->boot(); $this->assertNotNull($this->authCallback); } // 测试无Authorization头时返回null public function testAuthCallbackReturnNullWithoutAuthorizationHeader() { $this->provider->boot(); unset($_SERVER['HTTP_AUTHORIZATION']); $request = request(); // 模拟空请求 $result = call_user_func($this->authCallback, $request); $this->assertNull($result); } // 测试有Authorization头时返回User实例 public function testAuthCallbackReturnUserWithAuthorizationHeader() { $this->provider->boot(); $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer test_token'; $request = request(); $result = call_user_func($this->authCallback, $request); $this->assertInstanceOf(User::class, $result); } // 清理环境 public function tearDown(): void { unset($_SERVER['HTTP_AUTHORIZATION']); \Mockery::close(); parent::tearDown(); } }
额外注意
你贴出的AuthServiceProvider代码存在语法错误:viaRequest方法调用缺少右括号,类结尾多了一个多余的右大括号,正式运行前需要先修正语法问题。
内容的提问来源于stack exchange,提问作者unitSphere
相关产品推荐
相关产品推荐

