CakePHP 3模拟授权

3

目前我正在尝试测试一个控制器,该控制器使用身份验证组件来检索用户ID。由于我对单元/集成测试相当新,所以不知道如何使其工作。此外,我能找到的所有关于这个特定问题的内容都是针对Cakephp 2版本编写的。

控制器函数:

 public function favorite(){
    // Particular line where the problem is occurring:
    $userId = $this->Auth->User()['id'];
    // Get all favorite pictures of the user
    $query = $this->UsersPictures->getFavoritePictures($userId);

    $results = $query->all();
    // Replace the link in the result set by a presigned url of Amazon
    foreach($results as $result){
        $result->picture->link = $this->Aws->getTokenizedItem($result->picture->link);
    }
    $this->set([
        'success' => true,
        'data' => [
            'pictures' => $results
        ],
        '_serialize' => ['success', 'data']
    ]);
}

Integration test:

public function testFavoriteShouldPass(){
    $this->configRequest([
        'headers' => [
            'Accept' => 'application/json'
        ]
    ]);
    $this->get('api/pictures/favorite/1.json');

    $expected = [
        'success' => true,
        'data' => [
                [
                'user_id' => 1,
                'picture_id' => 1,
                'created' => '2016-04-03T20:35:40+0000',
                'modified' => '2016-04-03T20:35:40+0000',
                'picture' => [
                    'id' => 1,
                    'album_id' => 1,
                    'description' => 'Lorem ipsum dolor sit amet',
                    'link' => 'test',
                    'favorite' => true,
                    'created' => null,
                    'modified' => null,
                    'cover_photo' => true
                ]
            ]
        ]
    ];
    $this->assertEquals($expected, $response);
}

我的问题是如何插入一个默认id为1的用户到$this->Auth->User()['id']。我在其他问题中看到需要使用类似以下代码:
   $this->_controller->Auth
        ->staticExpects($this->any())
        ->method('user')
        ->will($this->returnValue([
            'id' => 1,
            'username' => 'admin',
            'created' => '2013-05-08 00:00:00',
            'modified' => '2013-05-08 00:00:00',
            'email' => 'me@me.com',
        ]));

然而,我读到从phpunit版本3.8开始,staticExpects已被弃用(我使用的是5.2版本)。我该如何模拟它?


我觉得你没有理解这个问题。问题是我想在测试过程中给$this->Auth->User('id')赋一个固定的值(比如用户ID始终为1)。这样,我就可以测试控制器的操作是否按照预期工作了。 - markvdlaan93
2个回答

1
您可以使用$this->session()在集成测试中设置会话数据,例如(摘自CakePHP书籍):
// Set session data
$this->session([
    'Auth' => [
        'User' => [
            'id' => 1,
            'username' => 'testing',
            // other keys.
        ]
    ]
]);

你可以在他们的文档中找到它:http://book.cakephp.org/3.0/en/development/testing.html#controller-integration-testing 你可以在以下章节中找到它:
测试需要身份验证的操作
如果您想在每个测试中使用相同的会话数据,可以使用集成测试类的setUp方法,如下所示:
public function setUp()
{
    parent::setUp();
    // Set session data
    $this->session([
    'Auth' => [
        'User' => [
              'id' => 1,
              'username' => 'testing',
              // other keys.
            ]
        ]
    ]);
}

抱歉,我想我忘了告诉你我使用无状态认证,因此没有使用任何会话。在正常情况下,这将是正确的方法,但我在Cakephp文档中找不到任何解决这个特定问题的内容。 - markvdlaan93
1
你尝试过使用controllerSpy函数吗?像这样:public function controllerSpy($event) { parent::controllerSpy($event); if (isset($this->_controller)) { $this->_controller->Auth->setUser(['username' => 'admin', 'is_admin' => true]); } } - azahar
不错!这真的完成了任务。我已经使用全局状态变量绕过了它,但这是一个更好的解决方案。 - markvdlaan93
1
好的,我在这里找到了这个链接:http://stackoverflow.com/questions/35958132/allow-all-actions-for-authentication-in-integration-test-cakephp 如果你想要阅读整个内容。 - azahar

1
感谢 azahar :), 这对我有用:
public function controllerSpy($event)
{
    parent::controllerSpy($event);

    if (isset($this->_controller)) {
        $this->_controller->Auth->setUser([
            'id' => 1,
            'username' => 'testtesttesttest',
            'email' => 'john@doe.com',
            'first_name' => 'John',
            'last_name' => 'Doe',
            'uuid' => 'wepoewoweo-ew-ewewpoeopw',
            'sign_in_count' => 1,
            'current_sign_in_ip' => '127.0.0.1',
            'active' => true
        ]);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接