Koneksi CakePHP saat pengujian

Saat ini saya sedang mencoba menguji unit beberapa kode saya. Saya menjalankan beberapa pernyataan SQL yang dimasukkan secara manual seperti ini:

$db = ConnectionManager::get('default');
...
$stmt = $db->prepare($sql);
$stmt->execute();

Saya berasumsi bahwa setiap kali saya menjalankan pengujian unit dan meminta koneksi default, saya akan mendapatkan koneksi test sebagai gantinya. Jika tidak ditentukan dalam konfigurasi saya, itu akan menimbulkan pengecualian. Ketika saya menjalankan tes yang mengeksekusi pernyataan terhadap database, pernyataan itu selalu dieksekusi terhadap koneksi default. Koneksi test tidak pernah digunakan.

Tahu apa yang saya lakukan salah?

Konfigurasi database saya adalah sebagai berikut:

'Datasources' => [
    'default' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'dbname',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],

    /**
     * The test connection is used during the test suite.
     */
    'test' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'localhost',
        'username' => 'root',
        'password' => '',
        'database' => 'dbname_test',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ],
]

Terima kasih atas bantuannya!

Edit Menurut saya dokumentasinya salah:

Secara default CakePHP akan alias setiap koneksi di aplikasi Anda. Setiap koneksi yang ditentukan dalam bootstrap aplikasi Anda yang tidak dimulai dengan test_ akan memiliki alias awalan test_ yang dibuat. Aliasing koneksi memastikan, Anda tidak menggunakan koneksi yang salah secara tidak sengaja dalam kasus pengujian. Aliasing koneksi bersifat transparan untuk seluruh aplikasi Anda. Misalnya jika Anda menggunakan koneksi 'default', Anda akan mendapatkan koneksi pengujian dalam kasus pengujian. Jika Anda menggunakan koneksi 'replika', rangkaian pengujian akan mencoba menggunakan 'test_replica'.

Tautan

Anda dapat membaca di sana bahwa CakePHP secara otomatis membuat koneksi default menjadi test saat menjalankan pengujian unit. Untuk mendapatkan perilaku itu, Anda harus mendefinisikan sendiri alias itu di phpunit bootstrap.php Anda seperti:

\Cake\Datasource\ConnectionManager::alias('test', 'default');

Anda dapat membacanya di sini ConnectionManager::alias lucunya dokumentasi untuk alias menyatakan secara eksplisit

Misalnya, jika Anda menggunakan alias 'default' menjadi 'test', mengambil 'default' akan selalu mengembalikan koneksi 'test' selama alias tersebut ditentukan.


person AlexWerz    schedule 20.04.2015    source sumber
comment
Konfigurasi test digunakan saat Anda menggunakan ClassRegistry::init untuk membuat instance model. Saat Anda menggunakan koneksi manual seperti yang Anda gunakan, Anda perlu mendapatkan koneksi test secara manual. Perlu dicatat bahwa di CakePHP 3.0 koneksi default akan dijadikan alias ke pengaturan pengujian untuk mencegah masalah seperti ini.   -  person jeremyharris    schedule 20.04.2015
comment
Biasanya yang Anda harapkan adalah perilaku default. Pastikan Anda menggunakan konfigurasi PHPUnit yang benar, dan konfigurasi tersebut menyertakan pendengar untuk CakePHP Fixture Injector, karena di sinilah alias default => test sedang dikonfigurasi.   -  person ndm    schedule 20.04.2015
comment
@jeremyharris Pertanyaan ini tentang CakePHP 3.x, yang cara kerjanya berbeda.   -  person ndm    schedule 20.04.2015
comment
@ndm ya Saya baru menyadarinya, langsung mengambil tindakan dan mendapatkan komentar Anda saat saya mengedit dokumen asli saya.   -  person jeremyharris    schedule 20.04.2015
comment
@jeremyharris Jika koneksi default diberi alias test kode saya di atas akan berfungsi, bukan? Atau apakah saya harus mendapatkan nama koneksi yang berbeda?   -  person AlexWerz    schedule 21.04.2015
comment
Saya memecahkan kebingungan saya :-) Anda harus melakukan \Cake\Datasource\ConnectionManager::alias('test', 'default'); di test-bootstrap Anda. Dokumentasi pengujian di CakePHP memberi tahu saya bahwa ini dilakukan untuk saya oleh CakePHP sendiri, namun tampaknya ini salah: Buku CakePHP - Pengujian Mereka menyatakan: For example if you use the ‘default’ connection, instead you will get the test connection in test cases.   -  person AlexWerz    schedule 21.04.2015
comment
Tidak, itu benar, seperti yang telah saya sebutkan, ini terjadi melalui injektor perlengkapan, tepatnya, ini terjadi di FixtureManager::_aliasConnections(). Anda harus men-debug mengapa testsuite tampaknya tidak berhasil sampai di sana.   -  person ndm    schedule 21.04.2015
comment
Dokumen pengujian tampaknya mengabaikan bagian penting tentang pembuatan file bootstrap. Biasanya saya menyalin bootstrap tes Cake (dan memodifikasi), atau DebugKit jika saya sedang mengerjakan sebuah plugin. Karena Anda tidak menggunakan perlengkapan, Anda tidak mendapatkan beberapa fungsi aliasing otomatis.   -  person jeremyharris    schedule 21.04.2015


Jawaban (2)


Aliasing koneksi dilakukan secara default ketika Anda memuat pendengar manajer perlengkapan di konfigurasi phpunit.xml kami saat didistribusikan dalam templat aplikasi:

https://github.com/cakephp/app/blob/master/phpunit.xml.dist#L23-L31

person José Lorenzo Rodríguez    schedule 21.04.2015
comment
Menerima ini sebagai jawabannya. Seperti yang ditunjukkan @jerremyharris dalam komentar di atas, dokumen mengabaikan bagian pembuatan file bootstrap. - person AlexWerz; 22.04.2015

Kami juga mengalami kesalahan yang sama, karena beberapa tabel pengujian mendapatkan db default alih-alih pengujian db tanpa alasan. Pada akhirnya menggunakan kode di bagian atas fungsi setUp (sebelum induk::setUp()) menyelesaikan masalah (kami memiliki kelas pengujian utama tempat kami memperluas semua pengujian, lakukan beberapa pengaturan. Kami meletakkannya di sana)

TableRegistry::clear();
person Bora Yalcin    schedule 09.08.2017
comment
Terima kasih banyak, solusi ini juga membantu saya! - person Levsha; 13.01.2021