2017-07-11 29 views
0

我有一個使用MySQL的gRPC服務,需要在每個測試用例後清除記錄。我嘗試用事務來包裝每個測試用例。如果我的rpc代碼中沒有事務,但是如果沒有事務,它就會起作用。而且還會有類似的錯誤:如何測試使用數據庫(mysql)的Go代碼?

can't start transaction 
... 
sql: Transaction has already been committed or rolled back 

然後我嘗試使用截斷清除記錄,但一些測試用例失敗隨機。

我的代碼是這樣(我用GORM):

func foo(db *gorm.DB) { 
    tx := db.Begin() 
    // query and insert 
    tx.Commit() 
} 
// Use transaction to do database cleanup 
func TestFooVersion1() { 
    testDB := initDB() 
    tx = testDB.Begin() // setup 
    foo(testDB) 
    tx.Rollback() // teardown 
} 
// Use truncate to do database cleanup 
func TestFooVersion2() { 
    testDB := initDB() 
    foo(testDB) 
    truncateTables(testDB) // teardown 
} 
func truncateTables(db *gorm.DB) { 
    // exec "TRUNCATE TABLE table;" for every table 
} 

什麼是測試使用DB(MySQL的)代碼有道? (我不喜歡像go-sqlmock模擬)

回答

0

很難說沒有看到代碼,但基於錯誤,它聽起來像你在多個測試之間共享連接,並且每個人都試圖啓動一個交易。確保每個測試都打開自己的連接,啓動自己的事務,並在完成時提交或回滾並關閉連接。

+0

我添加了一些示例代碼。問題是如果我在測試代碼中使用事務(如'foo'函數),事務不起作用。 –

0

也許你可以使用docker進行集成測試。直接測試生成的具有活動mysql的容器。

您可以使用testify的測試套件。 每次測試時,運行docker容器,並使用live mysql進行測試。

+0

我有一個用於測試的mysql。但它不起作用。順便說一句,我添加了一些示例代碼來解釋我的問題。 –

+0

我明白了。您的解決方案是爲每個測試用例啓動一個新的Docker容器。對? –

+0

是的......它會直接測試一個活的mysql –