在進行軟體開發時,經常會遇到需要模擬資料庫連線的情況,以便進行測試。然而,有時候我們可能沒有sqlmock這樣的工具來幫助我們實現這個目標。那麼,在沒有sqlmock的情況下,我們該如何模擬資料庫的ping操作呢?在本文中,php小編柚子將為您介紹一種簡單而有效的方法來實現這個目標,讓您能夠順利進行資料庫連接的模擬測試。
我想了解如何使用 mock.mock
重構我的程式碼以模擬 db.ping()
。我想先在沒有框架的情況下理解這個概念。
這是我要測試的程式碼:
func Connect() (*sql.DB, error) { db, err := sql.Open("mysql", "root:secret@tcp(s-maria-db)/s_db") if err != nil { return nil, err } for i := 0; i < 60; i++ { // I am hoping to mock this portion if err := db.Ping(); err == nil { break } time.Sleep(time.Second) } return db, nil }
我嘗試了這篇文章如何模擬 ping 命令,但這實際上並沒有回答問題。如果是這樣,我不理解該解決方案,因為它適用於我的程式碼。
您需要使用單獨的函數進行ping,並且它需要接受一個接口,以便您可以有條件地傳入真實的*sql.db
#或模擬。這是因為您無法重寫結構上的方法。
// connect opens a connection to the database. func connect() (*sql.db, error) { return sql.open("mysql", "root:secret@tcp(s-maria-db)/s_db") } // pinger defines an interface for pinging. type pinger interface { ping() error } // ping attempts to ping the database, trying several times before failing. func ping(p pinger) error { const maxattempts = 60 var err error for i := 0; i < maxattempts; i++ { if err = p.ping(); err == nil { return nil } if i < maxattempts - 1 { time.sleep(time.second) } } return err }
func main() { if err := run(); err != nil { log.fatal(err) } } func run() error { db, err := connect() if err != nil { return fmt.errorf("connecting to db: %w", err) } defer db.close() if err = ping(db); err != nil { return fmt.errorf("pinging db: %w", err) } ... }
type mockDB struct { mock.Mock } func (m *mockDB) Ping() error { args := m.Called() return args.Error(0) } func TestPing(t *testing.T) { db := &mockDB{} db.On("Ping").Return(...) err := Ping(db) ... db.AssertExpectations(t) }
以上是如何在沒有 sqlmock 的情況下模擬 db ping的詳細內容。更多資訊請關注PHP中文網其他相關文章!