如何在库项目中测试 Yii2 模型?

Posted

技术标签:

【中文标题】如何在库项目中测试 Yii2 模型?【英文标题】:How can I test a Yii2 model in a library project? 【发布时间】:2019-02-17 15:28:32 【问题描述】:

我正在尝试实现一个使用 Yii 模型对象扩展 yii\db\ActiveRecord 的适配器。该对象作为构造函数 arg 传递给适配器类。

我现在的问题是我仍然无法弄清楚如何让它正常工作。我什至尝试过模拟它,但因为 Yii 使用大量静态方法来获取它的对象而被卡住了。当然,我现在可以尝试模拟它们……但一定有更好的方法吗?

public function testSuccessFullFind(): void

    $connection = (new Connection([
            'dsn' => 'sqlite:test'
        ]))
        ->open();

    $queryBuilder = new \yii\db\sqlite\QueryBuilder($connection);

    $app = $this->createMock(Application::class);
    \Yii::$app = $app;

    $app->expects($this->any())
        ->method('getDb')
        ->willReturn($this->returnValue($connection));

    $userModel = new UserModel();
    $resovler = new Yii2Resolver($userModel);
    $result = $resolver->find(['username' => 'test', 'password' => 'test']);
    // TBD asserts for the result

UserModel 用于在内部查找用户记录。

这会导致:

1) Authentication\Test\Identifier\Resolver\Yii2ResolverTest::testSuccessFullFind
Error: Call to a member function getDb() on null

vendor\yiisoft\yii2-dev\framework\db\ActiveRecord.php:135
vendor\yiisoft\yii2-dev\framework\db\ActiveQuery.php:312
vendor\yiisoft\yii2-dev\framework\db\Query.php:237
vendor\yiisoft\yii2-dev\framework\db\ActiveQuery.php:133
tests\TestCase\Identifier\Resolver\Yii2ResolverTest.php:31

上面的代码显然是一个测试用例的WIP。

那么如何配置测试连接并让我的 ActiveRecord 对象使用它?

【问题讨论】:

【参考方案1】:

您可以将连接作为all() 方法的参数传递:

$results = UserModel::find()->where(['id' => 1])->all($connection);

【讨论】:

这对我没有帮助,因为我必须将 ActiveRecord AND 连接传递给我正在编写的 Adapter 类。抱歉,这是我的错,带有 find 的那一行只是为了测试查询是否有效。我不打算把它留在测试中,它会进入适配器类。我已经更新了代码和问题。 好吧,您可能应该允许将Connection 实例传递给您的适配器(作为可选参数,与all() 相同),因此它可以用于与AR 中定义的不同连接。出于测试目的,您可以创建自定义 AR 模型并覆盖 getDb() 以返回连接实例,而无需触及静态应用程序实例。 是的,我已经考虑过了,但不确定这在 Yii2 中是否常见?我希望这个库/适配器对框架的用户来说易于使用和熟悉。框架的架构似乎是高度耦合和依赖的,而且所有这些静态调用都不容易模拟。 :( 如果有人使用Yii2 AR,他可能已经初始化了应用程序并且AR默认使用Yii::$app->db,所以整个问题根本不存在。允许选择性地通过连接不会损害便利性,但会使其更加灵活。

以上是关于如何在库项目中测试 Yii2 模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在库项目中引用资产

Yii2 跨库orm实现

Yii2:如何在 mPDF 中添加模型和模型 id

Yii2 - 在模型中提交时如何从小部件中获取数据?

使用 mockeryBuilder() 在没有数据库的情况下测试 Yii2 中的存在验证器

如何将Yii2模型作为数组?