4

このプロジェクト構造を持つGOプロジェクトがあります(各パッケージにこの種のファイルが複数あります)。

- api
    - userHandler.go
    - userHandler_test.go
- database
    - user.go
    - user_test.go

user.go 内には、User 構造体と、ユーザーを作成/取得/更新する関数があります (私は GORM を使用していますが、これは問題ではありません)。user_test.go で。

異なるファイルごとに (すべてのデータを削除するか、特定の状態で) DB をクリーンアップしたいので、ファイルごとに 1 つのスイート (Testify を使用) を作成してから、SetupSuite 関数を使用しようとしましたが、動作は決定論的ではないようで、おそらく私は何か間違ったことをしています。

だから私の質問は:

  • DB接続を共有する最良の方法はどれですか? グローバル変数を使用するのが最善の選択肢ですか?
  • DB にテーブルを一度作成し、各 file_test.go を実行する前にカスタム データで DB を初期化する最良の方法はどれですか?

現在、私も奇妙なバグを抱えています:実行中

go test path/package1
go test path/package2

すべて正常に動作しますが、実行すると (すべてのパッケージをテストするため)

cd path && go test ./...

決定論的ではないように見えるエラーがあります。そのため、DB 接続が適切に処理されていないと推測しています

4

1 に答える 1

1

あなたのパッケージがあなたのapiパッケージに依存している場合database(そう見える)、あなたのapiパッケージにはデータベース接続プール (例えば ) を提供する方法が必要*sql.DBです。

パッケージのテストでは、api使用できる初期化されたプール (おそらくテスト スキーマ/フィクスチャが事前設定されている) を渡す必要があります。これは、パッケージinit()用に初期化するグローバルか、各テスト関数のandパターンのいずれかです。apisetup()defer teardown()

これは、テストで使用する共有データベースとスキーマを作成するだけの前者の (最も単純な) アプローチです。

package database

import testing

var testDB *sql.DB

// This gets run before your actual test functions do.
func init() {
    var err error
    db, err = sql.Open(...)
    if err != nil {
        log.Fatalf("test init failed: %s", err)
    }

    _, err := db.Exec(`CREATE TABLE ....`)
    if err != nil {
        log.Fatalf("test schema creation failed: %s", err)
    }
}

いくつかのヒント:

  • 関数を呼び出しsetup()て、ランダムな接尾辞を持つテーブルを作成し、テスト データを挿入して、テストで同じテスト テーブルを使用しないようにすることもできます (したがって、競合したり、相互に依存したりするリスクがあります)。そのテーブル名をキャプチャして、defer teardown()関数にダンプします。
  • https://medium.com/@benbjohnson/structuring-applications-in-go-3b04be4ff091は、追加の視点について読む価値があります。
于 2015-06-26T01:37:52.617 に答える