При Юнит Тестах есть ошибка Call to a member function getDb() on null

Сразу скажу, ошибка я знаю о чём, но проблема глубже, т.к. она проявляется исключительно на Юнит Тестировании.

Если делать перебор данных из модели в методе тестирования, то всё работает.

Рабочий вариант:

<?php

namespace tests\unit\services\user;

use app\models\User;
use app\services\User as UserService;

use Codeception\Test\Unit;

class UserTest extends Unit {
    
    /**
     * @var \UnitTester
     */
    protected $tester;  
    protected function _before() { }    
    protected function _after() { }
    
    public function testUserIsActive() {    
        $users = [
            User::findOne(['id' => 1]),
            User::findOne(['id' => 2]),
        ];
        
        foreach ($users as $user) {
            $userService = new UserService($user);
            self::assertEquals($userService->isActive(), true);
        }
    }
}

Если же данные выносить в метод и прикреплять аннотацию @dataProvider, то вылетает ошибка указанная в шапке вопроса

Нерабочий вариант:

<?php

namespace tests\unit\services\user;

use app\models\User;
use app\services\User as UserService;

use Codeception\Test\Unit;

class UserTest extends Unit {
    
    /**
     * @var \UnitTester
     */
    protected $tester;  
    protected function _before() { }    
    protected function _after() { }
    
    /**
    * @dataProvider getUsers
    */
    public function testUserIsActive($user, $result) {  
        $userService = new UserService($user);
        self::assertEquals($userService->isActive(), $result);
    }
    
    public function getUsers() {
        return [
            [User::findOne(['id' => 1]) => true],
            [User::findOne(['id' => 2]) => true],
        ];
    }
}

В инете писали, что проблема в старой версии codeception и надо поставить 2.4 и выше (например тут: https://godmodeuser.com/p/11 этим лечат несколько степеней member function). Поставил 2.5.6, ошибка осталась

"codeception/codeception": "2.5.6",
"codeception/verify": "1.0.0",
"codeception/specify": "1.0"

Может быть надо настройки какие-то дополнительные прописывать где-либо?

В папке test/_bootstrap.php

<?php
ini_set('xdebug.max_nesting_level', 1000);

define('YII_ENV', 'test');
defined('YII_DEBUG') or define('YII_DEBUG', true);

require_once __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
require __DIR__ .'/../vendor/autoload.php';

$config = require(__DIR__ . '/../config/test.php');
Yii::setAlias('@app', __DIR__ . '/../');

index-test.php

<?php

// NOTE: Make sure this file is not accessible when deployed to production
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) {
    die('You are not allowed to access this file.');
}

defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

$config = require __DIR__ . '/../config/test.php';

(new yii\web\Application($config))->run();

Ответы (1 шт):

Автор решения: Сергей О.

С ответом помогли на форуме фреймворка:

Во-первых, из провайдера возвращайте значения через запятую:

public function getUsers() {
    return [
        [User::findOne(['id' => 1]), true],
        [User::findOne(['id' => 2]), true],
    ];
}

Во-вторых, сравнивайте в другую сторону:

self::assertEquals($result, $userService->isActive());

В третьих, для борьбы с ошибкой вместо самого юзера из провайдера передавайте id:

/**
 * @dataProvider getUsers
 */
public function testUserIsActive($id, $result) {
    $user = User::findOne(['id' => $id]);
    $userService = new UserService($user);
    self::assertEquals($result, $userService->isActive());
}
        
public function getUsers() {
    return [
        [1 true],
        [2, true],
    ];
}
→ Ссылка