如何在功能测试中将值设置为 $_SERVER['var']?

How to set a value to $_SERVER['var'] on a functional testing?

我要根据系统从 $_SERVER['AUTH_USER'] 获得的 ID 创建一个 'autologin'。在我的业务服务器中,该值是 always 为经过身份验证的用户设置的。现在,我正在尝试测试我的自动登录(以及许多其他依赖自动登录工作的东西)所以我需要将一些用户设置为该全局(只是一个字符串)。

我试过的

$_SERVER['AUTH_USER'] = 'someUser';
$I->amOnPage('some-route'); // this page redirects to autologin action where $_SERVER is used to get the user logged.

但是当加载自动登录操作时,该值不再在 $_SERVER 全局中,我的测试崩溃了。

我想知道的

在哪里或如何设置全局值,以便我的页面可以正常运行,读取该值并继续。

如有任何帮助,我将不胜感激。 谢谢你。

目前,我正在使用一种变通方法,因为只有一个地方会检查该变量值:

//Inside my action autologin:
$authUser = explode('\', ($_SERVER['AUTH_USER'] ?? (YII_ENV_TEST ? 'domain\x12345' : 'domain\xInvalid')))[1];

这里唯一相关的一点是YII_ENV_TEST,即测试时的true。使用它,我可以设置一个足以进行简单测试的特定值。

不过我希望在这里看到任何其他更好的主意! 谢谢

看起来缺少适当的抽象。您应该避免直接在您的应用程序中访问 $_SERVER['AUTH_USER'] 并且最多在一个地方进行访问 - 在为此提供抽象的组件中。所以你应该扩展 yii\web\Request 并为 $_SERVER['AUTH_USER'] 抽象添加相关方法:

class MyRequest extends \yii\web\Request {

    private $_myAuthUser;

    public function getMyAuthUser() {
        if ($this->_myAuthUser === null) {
            $this->_myAuthUser = $_SERVER['AUTH_USER'];
        }

        return $this->_myAuthUser;
    }

    public function setMyAuthUser($value) {
        $this->_myAuthUser = $value;
    }
}

在您的配置中使用新的 class:

return [
    'id' => 'app-web',
    // ...
    'components' => [
        'request' => [
            'class' => MyRequest::class,
        ],
        // ...
    ],
];

并在您的操作中使用抽象:

$authUser = explode('\', Yii::$app->request->getMyAuthUser())[0];

在您的测试中,您可以使用 setter 在 MyRequest:

中设置值
 Yii::$app->request->setMyAuthUser('domain\x12345');

或在配置级别配置:

return [
    'id' => 'app-test',
    // ...
    'components' => [
        'request' => [
            'class' => MyRequest::class,
            'myAuthUser' => 'domain\x12345',
        ],
        // ...
    ],
];

更新:

根据 slinstj 评论,Codeception 可能会丢失 request 组件的状态,包括 myAuthUser 值。在这种情况下,在不同的组件(例如 Yii::$app->user)上实现 getMyAuthUser()setMyAuthUser() 或为此创建单独的组件可能是个好主意:

return [
    'id' => 'app-web',
    // ...
    'components' => [
        'authRequest' => [
            'class' => MyRequest::class,
        ],
        // ...
    ],
];