如何使用phpunit模拟Yii@1.1的CActiveRecord避免使用null属性?

问题描述

旧版项目使用Yii@1.1。它的数据库实体是CActiveRecord的实例。

假设我有一个名为User的模型,该模型具有属性idfirstnamelastname

在服务DoSomethingWithUser中,我以只读方式访问实体:

class DoSomethingWithUser {
    public function doSth(User $user) {
        $id = $user->id;
        $name = $user->name;
        $lastname = $user->lastname;

        ...

        return $result;
    }
}

在服务的测试用例中,我想注入CActiveRecord的模拟,因此我天真的认为我可以做这样的事情:

class DoSomethingWithUserTest extends TestCase
    testdoSth() {
        /**
         * @var User|MockObject $user
         */

        $user = $this->createMock(User::class);
        $user->id = 23;
        $user->lastname = "LAST_NAME";
        $user->firstname = "FirsT_NAME";

        $actualResult = (new DoSomethingWithUser())->doSth($user);
        
        $this->assertSame($expectedResult,$actualResult);
    }

我也尝试过setAttributes

 $user->setAttributes(
     ['id' => 23,'firstname'  => 'FirsT NAME','lastname' => 'LAST NAME']
 );

没有成功。

在测试运行期间,这些属性始终为null

我认为这与CActiveRecord的神奇吸气剂有关,但我不知道如何去做。

如何模拟CActiveRecord属性

解决方法

偶然地我发现这样做:

$user = $this->createMock(User::class);
$user->setMethods(['attributes'])
$user->id = 23;
$user->lastname = "LAST_NAME";
$user->firstname = "FIRST_NAME";

按预期工作。虽然我不知道为什么。