【发布时间】:2016-09-08 21:34:02
【问题描述】:
我正在使用带有 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 记录。不是我的固定装置。
我错过了什么?
更新1: 以下是我的配置文件中定义的连接:
'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 夹具类)
<?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']);
}
}
}
}
【问题讨论】:
-
@AD7six 我在上面添加了我的数据库配置。它看起来对我来说是正确的,因为我定义了
default和test,并且在运行测试时我没有收到任何数据库连接错误。 -
您是否已将夹具监听器添加到您的 phpunit.xml 中?
-
@code-kobold oooo 我不确定!请提交并回答我应该检查的内容。
-
@emersonthis sql 日志更有用/相关,因为它将证明是否使用了错误的数据库,“替代”的关键点是提供足够的信息 重现问题;
App\TestSuite\Fixture\TestFixture现在你已经提供了它的源代码不允许这样做。 -
@AD7six 你能详细说明一下吗?为什么不允许?
标签: unit-testing cakephp phpunit cakephp-3.0