如何防止在使用 PHPUnit 模拟类时调用原始方法



根据我对 PHPUnit 文档的阅读,我希望以下代码能够创建 AuthorizationChecker 类的模拟,该模拟将在调用 isGranted() 方法时返回 false。但是,将改为调用原始方法。我做错了什么?

    $auth = $this->getMockBuilder('SymfonyComponentSecurityCoreAuthorizationAuthorizationChecker')
        ->disableOriginalConstructor()
        ->setMethods(['isGranted'])
        ->getMock();
    $auth->expects($this->any())
        ->method('isGranted')
        ->with($this->anything())
        ->will($this->returnValue(false));
    $this->assertFalse($auth->isGranted('TEST'));

setMethods()参数替换为 null 或空数组,或完全删除调用,都没有效果。删除expects()with()调用也是如此。

您要

模拟的方法被声明为最终方法,因此您无法按照文档中的说明测试双倍:

限制:最终方法、私有方法和静态方法 请注意,最后, 私有和静态方法不能存根或模拟。他们是 被 PHPUnit 的测试忽略双重功能并保留其 原始行为。

您可以查看此部分解决方案。

希望这个帮助

我能够通过模拟 AuthorizationChecker 类使用的所有内部结构,然后将我的模拟注入容器来实现这一点。

    $tokenMock = $this->getMockBuilder( UsernamePasswordToken::class )
                      ->disableOriginalConstructor()
                      ->setMethods( array( 'isAuthenticated' ) )
                      ->getMock();
    $tokenMock->method( 'isAuthenticated' )
              ->willReturn( true );
    $tokenStorageMock = $this->getMockBuilder( TokenStorage::class )
                             ->disableOriginalConstructor()
                             ->setMethods( array( 'getToken' ) )
                             ->getMock();
    $tokenStorageMock->method( 'getToken' )
                     ->willReturn( $tokenMock );
    $authenticationManagerMock = $this->getMockBuilder( AuthenticationManagerInterface::class )
                                      ->disableOriginalConstructor()
                                      ->getMock();
    $accessDecisionManagerMock = $this->getMockBuilder( AccessDecisionManager::class )
                                      ->disableOriginalConstructor()
                                      ->setMethods( array( 'decide' ) )
                                      ->getMock();
    $accessDecisionManagerMock->method( 'decide' )
                              ->willReturn( 'true' );
    $authorizationCheckerMock = $this->getMockBuilder( AuthorizationChecker::class )
                                     ->setConstructorArgs(
                                         array(
                                             $tokenStorageMock,
                                             $authenticationManagerMock,
                                             $accessDecisionManagerMock,
                                             false
                                         )
                                     )
                                     ->setMethods( array( 'isGranted' ) )
                                     ->getMock();
    $authorizationCheckerMock->method( 'isGranted' )
                             ->will( $this->returnValue( true ) );
    $this->getContainer()
         ->set( 'security.authorization_checker', $authorizationCheckerMock );

最新更新