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

Posted

技术标签:

【中文标题】如何使用 phpunit 模拟 Yii@1.1 的 CActiveRecord(避免空属性)?【英文标题】:How to mock CActiveRecord of Yii@1.1 with phpunit (avoid nulled properties)? 【发布时间】:2020-12-13 01:00:24 【问题描述】:

一个遗留项目使用 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 的属性?

【问题讨论】:

【参考方案1】:

我偶然发现这样做:

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

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

【讨论】:

以上是关于如何使用 phpunit 模拟 Yii@1.1 的 CActiveRecord(避免空属性)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHPUnit 中跨多个测试模拟测试 Web 服务?

PHPUnit:如何通过测试方法模拟内部调用的函数

如何在 PHPUnit / Laravel 中模拟 JSON 文件

在 PHPUnit 中调用路由时如何在 Laravel 8 中模拟 Eloquent 模型

PHPUnit 如何获得模拟方法的真实返回值?

PHPUnit 中的模拟与存根