unit-testing - CakePHP单元测试无法识别固定装置

标签 unit-testing cakephp phpunit cakephp-3.0

我在使用PHPunit v5.1.3的CakePHP v3.x上。而且我的单元测试似乎无法识别我的灯具的存在。看来测试正在从本地(default)数据库连接中读取。

这是我的TestCase类:

namespace App\Test\TestCase\Model\Table;

use Cake\Datasource\ConnectionManager;
use Cake\I18n\Time;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;

/**
 * App\Model\Table\ScreensTable Test Case
 *
 * @property \App\Model\Table\ScreensTable ScreensTable
 */
class ScreensTableTest extends TestCase
{
    /**
     * Fixtures
     *
     * @var array
     */
    public $fixtures = [
        'app.screens'
    ];

    /**
     * setUp method
     *
     * @return void
     */
    public function setUp()
    {
        parent::setUp();
        $config = TableRegistry::exists('Screens') ? [] : ['className' => 'App\Model\Table\ScreensTable'];
        $this->Screens = TableRegistry::get('Screens', $config);
    }

    public testSomethingHere(){
         $newScreen = $this->Screens->newEntity(['who' => 'cares']);
         $screen = $this->Screens->save($newScreen);
         // ^ This record will show up in my app's DB!
    }

这是我的夹具文件:
<?php
namespace App\Test\Fixture;

use App\TestSuite\Fixture\TestFixture;

/**
 * ScreensFixture
 *
 */
class ScreensFixture extends TestFixture
{
    /**
     * Records
     *
     * @var array
     */
    public $records = [
        [
            'id' => 2,
            'name' => 'Bla bla',
        ],
        ...

当我debug()$this->Screens->find('all')->order(['id'=>'ASC'])->first()返回的值时,我在数据库中看到第一个REAL记录。不是我的固定装置。

我想念什么?

UPDATE1:
这是我的配置文件中定义的连接:
'Datasources' => [
    'default' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Postgres',
        'persistent' => false,
        'host' => 'localhost',
        'port' => '5432',
        'username' => 'postgres',
        'password' => 'postgres',
        'database' => 'transitscreen',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],
    /**
     * Used by test suites
     */
    'test' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Postgres',
        'persistent' => false,
        'host' => 'localhost',
        'port' => '5432',
        'username' => 'postgres',
        'password' => 'postgres',
        'database' => 'ts_test',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],
],

更新
App\Test\Fixture的内容(不要以为这有什么有趣的事情……我认为这只是在扩展Cake Fixture类)
<?php

namespace App\TestSuite\Fixture;

use Cake\I18n\Time;
use Cake\TestSuite\Fixture\TestFixture as CoreTestFixture;

/**
 * Override core TestFixture.
 */
class TestFixture extends CoreTestFixture
{

    /**
     * Initialize the fixture.
     *
     * @return void
     * @throws \Cake\ORM\Exception\MissingTableClassException When importing from a table that does not exist.
     */
    public function init()
    {
        $this->setRecordTimestamps();
        $this->encodeJsonColumns();

        parent::init();
    }

    /**
     * Set record timestamps.
     *
     * - created
     * - modified
     *
     * @return void
     */
    public function setRecordTimestamps()
    {
        foreach (['created', 'modified'] as $timestampField) {
            if (array_key_exists($timestampField, $this->fields)) {
                foreach ($this->records as &$record) {
                    $record[$timestampField] = new Time();
                }
            }
        }
    }

    /**
     * Encode JSON columns.
     *
     * Bake will output JSON fields as arrays (because of the `JsonType` object mapped to this field) but since
     * migrations execute directly against the database we need to encode these fields manually before insertion.
     *
     * @return void
     */
    public function encodeJsonColumns()
    {
        $fixtureName = namespaceSplit(get_called_class())[1];
        if ($fixtureName === 'DatasourcesFixture' && array_key_exists('widget_options', $this->fields)) {
            foreach ($this->records as &$record) {
                $record['widget_options'] = json_encode($record['widget_options']);
            }
        }
    }
}

最佳答案

您是否尝试过通过以下方法来缩小问题的范围:

  • 使用App \ Test \ Fixture删除继承
  • 通过声明$fields属性来定义灯具架构。
  • 启用query logging

  • 这两种都是临时措施,试图使问题更易于解决。您可能还想在运行PHPUnit时使用--debug标志。这将使CakePHP输出用于创建固定装置的所有SQL。

    关于unit-testing - CakePHP单元测试无法识别固定装置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39400558/

    相关文章:

    AngularJS "No pending request to flush",同时使用 $resource 对 Controller 进行单元测试

    javascript - 如何模拟依赖关系以返回特定数据?

    php - CakePHP 错误 : Call to a member function find() on a non-object

    laravel - 时间戳使我的 phpunit 测试失败

    php - 可测试代码 - 小应用示例

    javascript - 在 Jasmine 中,如何测试使用 document.write 的函数

    python - 有什么区别? (由于多字符串中的前导空格,Python 单元测试失败(?))

    Cakephp 3.0 登录

    php - 带左连接的 cakephp select 语句

    Laravel 5.5 : Testing with DatabaseMigrations deletes all tables