具有不同表名和插件的 Cakephp 夹具

Posted

技术标签:

【中文标题】具有不同表名和插件的 Cakephp 夹具【英文标题】:Cakephp Fixture with different table name and in a plugin 【发布时间】:2020-03-23 23:50:24 【问题描述】:

我是使用 Cakephp 测试的新手,现在正在创建一个新插件,想为其创建单元测试。

新插件“MyPlugin”连接到多个数据库,其中一个与不遵循蛋糕命名标准的非蛋糕应用程序(迁移到蛋糕)共享。

我想创建的第一个测试是从“AppApiKey”表中获取一些数据 - 但是数据库中的名称都是小写的,没有“_”,所以是“appapikey”而不是“app_api_key”。

在名为“AppApiKeyFixture”的插件中创建了一个 Fixture

namespace MyPlugin\Test\Fixture;

use Cake\TestSuite\Fixture\TestFixture;

class AppApiKeyFixture extends TestFixture 
    public $connection = 'test_ctrller';
    public $table = 'appapikey';

    //public $import = [ 'table' => 'appapikey', 'connection' => 'ctrller' ];
    public $fields = [
        'id' => ['type' => 'string'],
        'key' => ['type' => 'string' ],
        'label' => 'text',
        'creationdstamp' => 'datetime',
        '_constraints' => [
            'primary' => ['type' => 'primary', 'columns' => ['id']]
        ]
    ];

    public $records = [ 
        [
            'id' => '03380d5b-1b05-467a-af32-ca8aecb4dcc6',
            'key' => '53b4359a-a7d9-d6d7-9853-e569f408eae9',
            'label' => 'MyLabel',
            'creationdstamp' => '2019-11-12 15:53:48.176576+00'
        ] 
    ];

我一直在尝试一些事情,无论您是否使用导入,似乎总是会完成描述(那么为什么 $fields 存在?)

填写“$fields”和“$records”。据我从文档中了解到并经历过:

    使用原始连接完成描述 在“test”/“test_xxx”连接中创建并填写了“test_xxx”表 测试在 test(_xxx) 连接上的表(+ $records 数据)上运行

但上面的夹具给了我

Cake\Database\Exception:无法描述 app_api_key。它有 0 列。

它是否需要在其他地方使用 '$table = xxx'?在文档中看不到它。

无论 '$table' 或 '$import' 填写什么,这种情况都会持续发生

在应用程序本身中,此表类有效:

namespace MyPlugin\Model\Table;

use Cake\ORM\Table;

class AppApiKeyTable extends Table  
    public function initialize(array $config) 
        parent::initialize($config);
        $this->setTable('appapikey');
    

    public static function defaultConnectionName() 
        return 'ctrller';
    

TestCase 调用我要测试的这个函数:

namespace MyPlugin\Auth\ApiKey;

use Cake\ORM\TableRegistry;

class ApiKeyAuthenticator 
    public function getApiKeyInfo($pKey) 
        return TableRegistry::getTableLocator()->get('AppApiKey')->findByKey($pKey)->first();
    

另外发现奇怪的是,在另一个 Fixture 中我必须使用“$import”,而没有它我也会得到一个:

Cake\Database\Exception:无法描述软件 ID。它有 0 列

夹具是:

namespace MyPlugin\Test\Fixture;

use Cake\TestSuite\Fixture\TestFixture;

class SoftwareidFixture extends TestFixture 
    //public $import = [ 'table' => 'softwareid', 'connection' => 'default' ];
    public $fields = [
        'id' => ['type' => 'string'],
        'softwareid' => ['type' => 'string' ],
        'name' => 'text',
        'created' => 'datetime',
        '_constraints' => [
            'primary' => ['type' => 'primary', 'columns' => ['id']]
        ]
    ];

    public $records = [ 
        [
            'id' => '5e26b612-2b74-40ed-aaa5-b48cb4b1d946',
            'softwareid' => '228ebfe2-4a2b-49ec-ab75-43f44007b68d',
            'name' => 'MySoftwarePackage',
            'created' => '2019-10-31 12:08:10+00'
        ] 
    ];

上面是默认连接中的表,'$fields'和'$records'应该够了吧,不需要定义'$import'

【问题讨论】:

【参考方案1】:

因此,导入后它对两个表都有效,在我的情况下,这是一个很好的修复,因为一旦迁移完成(长期项目),将有 70 到 100 个表

最简单的方法是定义模型,它在文档中,但我对文档中提到的“$table”、“$connection”和“$fields”视而不见。

所以夹具以:

namespace MyPlugin\Test\Fixture;

use Cake\TestSuite\Fixture\TestFixture;

class AppApiKeyFixture extends TestFixture 
    public $import = [ 'model' => 'AppApiKey', 'connection' => 'ctrller' ];
    public $records = [ 
        [
            'id' => '03380d5b-1b05-467a-af32-ca8aecb4dcc6',
            'key' => '53b4359a-a7d9-d6d7-9853-e569f408eae9',
            'label' => 'MyLabel',
            'creationdstamp' => '2019-11-12 15:53:48.176576+00'
        ] 
    ];

对于任何在让单元测试使用不同的表名和连接时遇到问题的人,引用模型似乎是要走的路。

【讨论】:

以上是关于具有不同表名和插件的 Cakephp 夹具的主要内容,如果未能解决你的问题,请参考以下文章

SQL VBA:选择具有特定表名和字段名的所有表

调用未定义的方法 Cake\ORM\Entity::query() CakePhp

php [cakephp:MediaController]用文件二进制文件返回cake的响应对象。 #cakephp

cakephp的 cake24CakeControllerBaseController.php

Cakephp cake_core_ 缓存无法写入“cake_dev_en-us”

为啥 CakePHP 无法为一个控制器创建夹具并返回 SQLSTATE[42000] 而它是为另一个控制器?