sql >> データベース >  >> RDS >> Mysql

メソッドを含むデータベースクエリをチェックするためのテスト駆動開発

    少し前に、自分のテストのいくつかをリファクタリングしたときに同様の質問がありました。それを実行する方法はいくつかあります。

    a)エクスポートされたタイプとOpenを提供します またはConnect それを返す関数-例:

    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
    }
    

    ...そしてそれぞれ テスト、*DBのインスタンスを返すセットアップおよびティアダウン関数の記述 データベース関数を(メソッドとして-つまり、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
    }
    

    これはやや「統合」テストであることに注意してください。ただし、インターフェースをモックしてもクエリ/クエリ構文の問題を見つけるのに役立たないため、「実際の」データベースに対してテストすることを強くお勧めします。

    b)代替手段は、アプリケーション側では拡張性が低くなりますが、グローバルなdb *sql.DBを使用することです。 init()で初期化する変数 テスト内-テストには保証された順序がないため、init()を使用する必要があります —そしてそこからテストを実行します。つまり、

    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)
       ...
    }
    

    いくつかの実用的な例は、drone.ioのGitHubリポジトリ> 、およびGoアプリケーションの構造化に関するこの記事> (特にDBのもの)。



    1. MySQL EntityFramework6でコンソールアプリを実行しようとしたときにConfigurationErrorExceptionが発生しました

    2. HibernateはデータベースからSequenceInformationをフェッチできませんでした

    3. PHP + MySQL CMSを自己更新する方法は?

    4. Django-MySQLデータベースに行を追加します