【问题标题】:Inject mocked component into controller - integration testing - cakephp 3将模拟组件注入控制器 - 集成测试 - cakephp 3
【发布时间】:2016-08-19 06:30:13
【问题描述】:

目前,我正在为使用组件的类编写集成测试。由于该组件使用第三方服务(在我的情况下为 AWS S3),因此我想用模拟组件替换该组件,以避免与第三方服务进行任何通信。

部分控制器类:

class AlbumsController extends AppController{
      public $components = ['Aws', 'Upload'];
      // Example of function that uses component
      public function add(){
            $album->pictures = $this->Aws->transformLinkIntoPresignedUrl($album->pictures);
      }
}

部分集成测试:

public function controllerSpy($event){
    parent::controllerSpy($event);
    if (isset($this->_controller)) {
        $this->_controller->Auth->setUser([
            'id' => $this->userId,
            'username' => 'testtesttesttest',
            'email' => 'john@doe.com',
            'first_name' => 'Mark',
            'last_name' => 'van der Laan',
            'uuid' => 'wepoewoweo-ew-ewewpoeopw',
            'sign_in_count' => 1,
            'current_sign_in_ip' => '127.0.0.1',
            'active' => true
        ]);
        // If the component is set, inject a mock
        if($this->_controller->Aws){
            $component = $this->getMock('App\Controller\Component\AwsComponent');
            $component->expects($this->once())
                ->method('transformLinkIntoPresignedUrl')
                ->will($this->returnValue(['link']));
            $this->_controller->Aws = $component;
        }
    }
}

由于这会引发 transformLinkIntoPresignedUrl 不存在的错误,我不确定我是否在正确的轨道上解决这个特定问题。因此,我的问题是如何将模拟/存根组件注入控制器并控制其行为(通过为方法设置固定的返回值)?

【问题讨论】:

    标签: cakephp phpunit integration-testing cakephp-3.0


    【解决方案1】:

    当我查看 IntegrationTestCase 的代码时,我发现不可能做你(和我)正在尝试做的事情。我能想到的最好的是:

    $this->controller = new AlbumsController();
    
    $this->controller->Aws = $this->createMock(AwsComponent::class);
    $this->controller->Aws
        ->expects($this->once())
        ->method('transformLinkIntoPresignedUrl');
    
    $this->controller->add();
    

    但这意味着您必须对 Flash、Auth、请求和其他您认为理所当然的调用进行模拟,因为控制器只是无效的。在这里,我达到了我的蛋糕知识的极限。

    【讨论】:

      【解决方案2】:

      我想自己做这件事,而我目前的决定是,集成测试是不可能的。如果您正在做更多的单元测试方法并直接测试您的控制器方法,那么模拟的创建将起作用,但它似乎无法获得请求以拥有一个在其中模拟任何内容的控制器实例。另一种略显老套的方法是使用一些标志或方法来指示您正在测试中。然后在你的实际控制器代码中,你可以在调用组件之前验证你没有在测试中。我使用了设置 IS_PHPUNIT 常量并检查它是否被定义并具有价值的策略。我想说这并不接近最佳实践,但有时在尝试弥合遗留/未经测试代码之间的差距并让一些测试正常工作时会有所帮助。

      【讨论】:

        猜你喜欢
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 2012-02-27
        • 2017-01-12
        • 2018-03-10
        • 1970-01-01
        • 1970-01-01
        • 2011-09-10
        相关资源
        最近更新 更多