การเชื่อมต่อ CakePHP ขณะทดสอบ

ฉันกำลังพยายามทดสอบโค้ดบางส่วนของฉัน ฉันกำลังดำเนินการคำสั่ง SQL ที่ป้อนด้วยตนเองดังนี้:

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

ฉันคิดว่าเมื่อใดก็ตามที่ฉันทำการทดสอบหน่วยและขอการเชื่อมต่อ default ฉันจะได้รับการเชื่อมต่อ test แทน หากไม่ได้กำหนดไว้ในการกำหนดค่าของฉัน มันจะเกิดข้อยกเว้น เมื่อฉันรันการทดสอบซึ่งดำเนินการคำสั่งกับฐานข้อมูล มันจะถูกดำเนินการกับการเชื่อมต่อ default เสมอ ไม่เคยใช้การเชื่อมต่อ test

มีความคิดอะไรบ้างที่ฉันทำอะไรผิด?

การกำหนดค่าฐานข้อมูลของฉันเป็นดังนี้:

'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,
    ],
]

ขอบคุณสำหรับความช่วยเหลือ!

แก้ไข ฉันคิดว่าเอกสารประกอบไม่ถูกต้อง:

ตามค่าเริ่มต้น CakePHP จะสร้างนามแฝงแต่ละการเชื่อมต่อในแอปพลิเคชันของคุณ การเชื่อมต่อแต่ละรายการที่กำหนดไว้ในบูตสแตรปของแอปพลิเคชันของคุณที่ไม่ได้ขึ้นต้นด้วย test_ จะมีการสร้างนามแฝงที่นำหน้า test_ การเชื่อมต่อนามแฝงช่วยให้แน่ใจว่าคุณไม่ได้ใช้การเชื่อมต่อที่ไม่ถูกต้องในกรณีทดสอบ นามแฝงการเชื่อมต่อมีความโปร่งใสกับส่วนที่เหลือของแอปพลิเคชันของคุณ ตัวอย่างเช่น หากคุณใช้การเชื่อมต่อ 'เริ่มต้น' คุณจะได้รับการเชื่อมต่อทดสอบในกรณีทดสอบแทน หากคุณใช้การเชื่อมต่อ 'replica' ชุดทดสอบจะพยายามใช้ 'test_replica'

ลิงก์

คุณสามารถอ่านได้ที่นั่นว่า CakePHP กำลังนามแฝงการเชื่อมต่อ default โดยอัตโนมัติเป็น test เมื่อรันการทดสอบหน่วย เพื่อให้ได้พฤติกรรมนั้น คุณต้องกำหนดนามแฝงนั้นด้วยตัวคุณเองใน phpunit bootstrap.php ดังนี้:

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

คุณสามารถอ่านเกี่ยวกับเรื่องนี้ได้ที่นี่ ConnectionManager::alias สิ่งที่ตลกก็คือเอกสารประกอบสำหรับ alias ระบุไว้อย่างชัดเจน

ตัวอย่างเช่น หากคุณใช้นามแฝงเป็น 'เริ่มต้น' เป็น 'ทดสอบ' การดึงข้อมูล 'ค่าเริ่มต้น' จะส่งกลับการเชื่อมต่อ 'ทดสอบ' เสมอตราบใดที่มีการกำหนดนามแฝงไว้


person AlexWerz    schedule 20.04.2015    source แหล่งที่มา
comment
การกำหนดค่า test จะใช้เมื่อคุณใช้ ClassRegistry::init เพื่อสร้างอินสแตนซ์ของโมเดล เมื่อคุณใช้การเชื่อมต่อด้วยตนเองเหมือนกับที่คุณใช้อยู่ คุณจะต้องรับการเชื่อมต่อ test ด้วยตนเอง เป็นที่น่าสังเกตว่าใน CakePHP 3.0 การเชื่อมต่อ default จะถูกนามแฝงกับการตั้งค่าการทดสอบเพื่อป้องกันปัญหาประเภทนี้   -  person jeremyharris    schedule 20.04.2015
comment
สิ่งที่คุณคาดหวังตามปกติคือพฤติกรรมเริ่มต้น ตรวจสอบให้แน่ใจว่าคุณใช้การกำหนดค่า PHPUnit ที่ถูกต้อง และรวม Listener สำหรับ CakePHP Fixture Injector ไว้ด้วย เนื่องจากนี่คือที่ที่กำหนดค่า default => test นามแฝง   -  person ndm    schedule 20.04.2015
comment
@jeremyharris คำถามนี้เกี่ยวกับ CakePHP 3.x ซึ่งทำงานแตกต่างออกไป   -  person ndm    schedule 20.04.2015
comment
@ndm ใช่ฉันเพิ่งสังเกตเห็นว่ากระโดดปืนขึ้นเล็กน้อยและรับความคิดเห็นของคุณในขณะที่ฉันแก้ไขต้นฉบับ   -  person jeremyharris    schedule 20.04.2015
comment
@jeremyharris หากการเชื่อมต่อ default ได้รับนามแฝงเป็น test รหัสของฉันด้านบนควรใช้งานได้ใช่ไหม หรือฉันต้องได้รับชื่อการเชื่อมต่อที่แตกต่างออกไป?   -  person AlexWerz    schedule 21.04.2015
comment
ฉันแก้ไขความสับสนของฉัน :-) คุณต้องทำ \Cake\Datasource\ConnectionManager::alias('test', 'default'); ใน test-bootstrap ของคุณ เอกสารการทดสอบใน CakePHP บอกฉันว่า CakePHP ทำเพื่อฉันเอง แต่ดูเหมือนว่าจะเป็นเท็จ: CakePHP Book - การทดสอบ ระบุว่า: 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
ไม่ มันเป็นเรื่องจริง อย่างที่ฉันได้พูดถึงไปแล้วว่าสิ่งนี้เกิดขึ้นผ่านฟิกซ์เจอร์อินเจคเตอร์ พูดให้ถูกก็คือมันเกิดขึ้นใน FixtureManager::_aliasConnections(). คุณควรแก้ไขว่าทำไมชุดทดสอบจึงไม่ไปที่นั่น   -  person ndm    schedule 21.04.2015
comment
เอกสารการทดสอบดูเหมือนจะไม่ได้มีส่วนสำคัญเกี่ยวกับการสร้างไฟล์บูตสแตรป โดยปกติแล้ว ฉันจะคัดลอกบูตสแตรปทดสอบของ Cake (และแก้ไข) หรือ DebugKit หากฉันกำลังทำงานกับปลั๊กอิน เนื่องจากคุณไม่ได้ใช้ฟิกซ์เจอร์ คุณจึงไม่ได้รับฟังก์ชันนามแฝงอัตโนมัติบางส่วน   -  person jeremyharris    schedule 21.04.2015


คำตอบ (2)


นามแฝงการเชื่อมต่อจะดำเนินการตามค่าเริ่มต้นเมื่อคุณโหลด Listener ตัวจัดการการติดตั้งในการกำหนดค่า phpunit.xml ของเราตามที่มีการเผยแพร่ในเทมเพลตแอป:

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

person José Lorenzo Rodríguez    schedule 21.04.2015
comment
ยอมรับสิ่งนี้เป็นคำตอบ ดังที่ @jerremyharris ชี้ให้เห็นในความคิดเห็นข้างต้น เอกสารจะละส่วนของการสร้างไฟล์บูตสแตรป - person AlexWerz; 22.04.2015

นอกจากนี้เรายังมีข้อผิดพลาดเดียวกัน เนื่องจากบางตารางการทดสอบได้รับ db เริ่มต้นแทนที่จะเป็น test db โดยไม่มีเหตุผล ในที่สุดการใช้โค้ดที่ด้านบนของฟังก์ชัน setUp (ก่อนที่ parent::setUp()) จะแก้ไขปัญหาได้ (เรามีคลาสการทดสอบหลักซึ่งเราขยายการทดสอบทั้งหมด ทำการตั้งค่าบางอย่าง เราวางไว้ที่นั่น)

TableRegistry::clear();
person Bora Yalcin    schedule 09.08.2017
comment
ขอบคุณมาก โซลูชันนี้ช่วยฉันด้วย! - person Levsha; 13.01.2021