2013-07-13 50 views
0

我一直在編寫我自己的PHP模型系統,它提供的基本ORM和DBAL支持僅僅是一個學習課程。它允許我編寫以前從未做過的事情,並使用SQLite和PostgreSQL等我從未使用過的數據庫。單元測試Postgresql PHP PDO失敗

模型包:https://github.com/titon/Model PGSQL包:https://github.com/titon/Model.PostgreSQL

我遇到的問題是單元測試PGSQL驅動程序(我有MySQL和SQLite的工作)。任何時候單元測試運行,我收到以下錯誤:我知道這個問題是什麼,但我似乎沒有做任何修復它。它甚至沒有達到我的單元測試,它在燈具設置部分失敗。下面是每個單元測試期間所採取的步驟:在setUp()

  • 單位測試方法

    1. 驅動被初始化並連接被稱爲
    2. 賽程被加載
      1. CREATE TABLE語句被稱爲
      2. CREATE INDEX報表被稱爲
      3. INSERT記錄被稱爲
    3. 單位測試跑
    4. tearDown()被稱爲其卸載夾具(DROP TABLE和INDEX)和斷開

    步驟3.3中,同時插入夾具記錄發生錯誤的驅動程序。它插入第一條記錄(滿分10),並且無法獲取最後一個插入ID(上面的序列錯誤)。當我檢查PGAdmin時,表格和序列確實存在,所以我很困惑。

    • 插入被調用時,序列是否尚未完全創建?
    • 我的連接會話是否過早死亡?
    • 我該如何解決這個問題?

    我對PgSQL很陌生,所以任何幫助將不勝感激。爲了記錄,代碼使用PHP PDO並調用lastInsertId('table_column_seq')來檢索最後一個ID。

    如果您有興趣,可以參考fixture setUp SQL。

    CREATE TABLE IF NOT EXISTS "users" (
        "id" serial NOT NULL, 
        "country_id" integer NULL DEFAULT NULL, 
        "username" varchar(255) NULL, 
        "password" varchar(255) NULL, 
        "email" varchar(255) NULL, 
        "firstName" varchar(255) NULL, 
        "lastName" varchar(255) NULL, 
        "age" smallint NULL, 
        "created" timestamp NULL DEFAULT NULL, 
        "modified" timestamp NULL DEFAULT NULL, 
        UNIQUE ("username") 
    ); 
    CREATE INDEX "country_id" ON "users" ("country_id"); 
    INSERT INTO "users" ("id", "country_id", "username", "firstName", "lastName", "password", "email", "age", "created") VALUES ('1', 1, 'miles', 'Miles', 'Johnson', '1Z5895jf72yL77h', '[email protected]', 25, '1988-02-26 21:22:34'); 
    # Fails right after this insert 
    
  • +0

    如果您要使用序列(SERIAL數據類型),爲什麼要在INSERT語句中傳遞一個文字ID?爲什麼你將該字面值作爲字符串而不是整數傳遞?爲什麼沒有主鍵?爲什麼用戶名是唯一的,但可以爲空? –

    +0

    固定裝置基本上是簡單的數據,隨機模式和亂七八糟的類型,其中一些在字面刺激設置中沒有意義。 Fixture也在MySQL,PgSQL,SQLite和MongoDB之間共享,所以有一些怪異的東西讓一切正常工作。 此外,語句輸出並不完全匹配,因爲PDO語句無法用其邊界值查看。這些只是自動生成的。 –

    回答

    2

    不要猜測,知道。打開語句登錄並查看它的作用。

    然後,您可能會看到lastInserId()調用正在從序列中獲取id上的最後一個id。沒有一個是因爲你提供了自己的價值。停止這樣做,它應該工作。

    +0

    啊這麼簡單的疏忽。 Fixtures用於MySQL,SQLite,PgSQL和MongoDB,所以這些ID是硬編碼的。如果我需要連接關係記錄,你會如何建議編寫單元測試? –

    +0

    如果你沒有在數據庫中生成ID,爲什麼要抓取last-insert-id呢?我不太明白這有什麼意義。如果您真的需要知道剛剛提供給數據庫的值,那麼您當然可以通過INSERT上的RETURNING子句返回ID。 –

    +0

    那麼我插入硬編碼的燈具記錄,但很多單元測試插入更多的行或刪除,所以它更容易硬編碼的ID。但假設我刪除了ID,他們都應該*按照正確的順序插入。 –