【问题标题】:+Testing an artisan command that edits the database+测试编辑数据库的工匠命令
【发布时间】:2015-06-24 14:50:34
【问题描述】:

我正在尝试测试一个旨在进行一些数据库维护的 artisan 命令。

特别是,它会搜索没有填满列的记录,然后将其填满。

这是命令的fire()方法的简化版:

public function fire()
{
    $items = Item::all();

    $total = $items->count();
    $updated = 0;

    foreach ($items as $item) {
        if ($item->myColumn != 'x') {
            $item->myColumn = 'x';
            $item->save();

            $updated++;
        }
    }

    $this->info("total: $total updated: $updated");
}

我的(验收)测试非常简单,并且执行以下操作:

  • 在数据库中插入一条记录
  • 调用artisan 命令
  • 检查插入的记录是否已更新

这是代码:

public function doTheTest(AcceptanceTester $I)
{
    $I->wantTo('setup the myColumn when it is not set');

    $id = $I->haveRecord('items', [
        'myColumn' => '',
    ]);

    $I->runShellCommand('php artisan items:updater');

    $I->seeRecord('items', [
        'id'       => $id,
        'myColumn' => 'x',
    ]);
}

但是测试失败,我收到以下消息:

Couldn't see record "items",{"id":101,"myColumn":"x"}:
Couldn't find items with {"id":101,"code":"x"}

如您所见,新记录的id是101,因为db转储中已经有100个项目,但奇怪的是命令中的$this->info()打印出来

total: 100 updated: 100

好像测试中使用的数据库和artisan中使用的数据库不同。

另外,如果在测试结束时我尝试抓取添加的记录,并打印出来,如下面的sn-p

public function doTheTest(AcceptanceTester $I)
{
    /* ... */

    $item = $I->grabRecord('items', [
        'id'       => $id,
    ]);

    \Codeception\Util\Debug::debug($item);
}

然后运行codecept run acceptance --debug 命令,我得到了添加的记录

stdClass Object
(
    [id] => 101
    [myColumn] =>
)

我很困惑,因为只有一个数据库,但我肯定误解了这里的重要内容。

谁能帮帮我?

非常感谢,

【问题讨论】:

    标签: php database laravel codeception laravel-artisan


    【解决方案1】:

    问题是每个使用 Laravel4 模块的查询都在一个事务中运行,默认情况下,最后会回滚。如果您查看 Laravel4 文档的 Config 部分,它会说明

    cleanup: boolean, 默认 true - 所有数据库查询都将在事务中运行,在测试结束时将回滚。

    如果您重新启动 MySQL 服务器,您可以检查这一点(在这种情况下,当您再次运行测试时,您仍然会看到 id 101),或者查看 MySQL 日志,其中将包含如下条目:每次测试:

    150417 23:24:24 2 在 laravel-test 上连接 root@localhost
    2 准备集合名称 'utf8' collat​​e 'utf8_unicode_ci'
    2 执行集名称 'utf8' collat​​e 'utf8_unicode_ci'
    2 关闭 stmt
    2 查询开始交易
    2 准备插入items (myColumn) 值 (?)
    2 执行插入items (myColumn) 值 ('')
    2 关闭 stmt
    2 查询回滚
    2 退出

    要解决这个问题,你需要在 codeception.yml 文件中配置 Laravel4 模块的选项 cleanup,如下所示:

    modules:
        config:
            Laravel4:
            cleanup: false
    

    【讨论】:

    • Laravel5 也是如此。因此,测试中的查询在与 artisan 命令中的不同事务中运行。现在可以了,谢谢。
    猜你喜欢
    • 2021-01-29
    • 2019-08-08
    • 1970-01-01
    • 2019-03-14
    • 2014-08-30
    • 2016-04-21
    • 2014-12-15
    • 2014-09-07
    • 2020-11-29
    相关资源
    最近更新 更多