Cách đây không lâu, tôi đã gặp một câu hỏi tương tự khi cấu trúc lại một số bài kiểm tra của riêng mình và bạn có thể thực hiện một số cách:
a) Cung cấp kiểu đã xuất và Open
hoặc Connect
hàm trả về nó - ví dụ:
type DB struct {
db *sql.DB
}
// Using http://jmoiron.github.io/sqlx/ for this example, but
// it has the same interface as database/sql
func Open(opts *Options) (*DB, error) {
db, err := sqlx.Connect(opts.Driver, fmt.Sprintf("host=%s user=%s dbname=%s sslmode=%s", opts.Host, opts.User, opts.Name, opts.SSL))
if err != nil {
return nil, err
}
return &DB{db}, nil
}
... và sau đó là mỗi người trong số các bạn kiểm tra, viết các hàm thiết lập &chia nhỏ trả về một bản sao của *DB
mà bạn xác định các chức năng cơ sở dữ liệu của mình trên (dưới dạng các phương thức - tức là func (db *DB) GetUser(user *User) (bool, error)
):
// Setup the test environment.
func setup() (*DB, error) {
err := withTestDB()
if err != nil {
return nil, err
}
// testOptions is a global in this case, but you could easily
// create one per-test
db, err := Open(testOptions)
if err != nil {
return nil, err
}
// Loads our test schema
db.MustLoad()
return db, nil
}
// Create our test database.
func withTestDB() error {
db, err := open()
if err != nil {
return err
}
defer db.Close()
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", testOptions.Name))
if err != nil {
return err
}
return nil
}
Lưu ý rằng đây là thử nghiệm hơi "tích hợp", nhưng tôi thực sự muốn thử nghiệm dựa trên cơ sở dữ liệu "thực" vì việc chế tạo giao diện sẽ không giúp bạn giải quyết các vấn đề với truy vấn / cú pháp truy vấn của mình.
b) Giải pháp thay thế, mặc dù ít mở rộng hơn ở phía ứng dụng, là có db *sql.DB
biến mà bạn khởi tạo trong init()
trong các thử nghiệm của bạn — vì các thử nghiệm không có thứ tự đảm bảo nên bạn cần sử dụng init()
—Và sau đó chạy các bài kiểm tra của bạn từ đó. tức là
var db *sql.DB
func init() {
var err error
// Note the = and *not* the assignment - we don't want to shadow our global
db, err = sqlx.Connect(...)
if err != nil {
...
}
err := db.loadTestSchema
// etc.
}
func TestGetUser(t *testing.T) {
user := User{}
exists, err := db.GetUser(user)
...
}
Bạn có thể tìm thấy một số ví dụ thực tế trong repo GitHub của drone.io và tôi cũng khuyên bạn nên dùng bài viết này về cấu trúc ứng dụng Go (đặc biệt là nội dung DB).