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

时间:2016-09-08 21:34:02

标签: unit-testing cakephp phpunit cakephp-3.0

我在CakePHP v3.x上使用phpunit v5.1.3。我的单元测试似乎没有认识到我的灯具的存在。看来测试是从本地(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()返回的值时,我看到了DB中的第一条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的内容(不要认为这里发生了一些有趣的事情......我认为它只是扩展了蛋糕夹具类)

<?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']);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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

  1. 使用App \ Test \ Fixture
  2. 删除继承
  3. 通过声明$fields属性来定义Fixture模式。
  4. 启用query logging
  5. 这些都是临时措施,试图让问题更容易解决。您可能还希望在运行PHPUnit时使用--debug标志。这将使CakePHP输出用于创建灯具的所有SQL。