dousha4804 2016-06-01 02:45
浏览 18
已采纳

Golang测试中可重复使用的组件和固定装置

I'm just getting started with Golang and writing my first test suite.

I have a background in Rails, which has fantastic support for testing tools (Rspec, Cucumber, etc..), so I'm approaching my golang tests with a similar mindset (not sure if that's the right or wrong thing to do)

I have a User data model (basically a struct) that reads records from a users table in postgres and stores an array of them. (Essentially a really simple version of what ActiveRecord does in the Rails world)

I'd like to write a test that checks if the routine correctly reads from the DB and builds the models.

  1. In almost every test suite I'll be connecting to the DB so I have a helper named establish_db_connection. Where can I place this so that it's centrally available to all my tests?

  2. Building off #1 - is there an equivalent of a before block or some setup/teardown method where I can establish a connection before every test?

  3. Lastly, how do I handle fixtures? Right now before each test I call a clear_db function that resets all tables and inserts some static data rows. I'd love to move away from fixtures and use factories to build data as needed (very similar to FactoryGirl in Rails), but not sure how common that is in Golang.

  4. Is the built-in go test framework the best approach, or are there better alternatives?

  • 写回答

2条回答 默认 最新

  • doumeng2637 2016-06-01 04:04
    关注
    1. Go is based on strong package management, meaning a namespace is treated as one single file. If establish_db_connection is used within a single test package, it can begin with a lowercase letter to signify a private instance and use it in the test file with the same package as the code being tested (Note that naming convention in Go is establishDBConnection). However, most of the time, as in data/sql, you will want to obtain a DB connection once and keep that around until the test is finished (more like a factory and injection pattern).

    2. There is none in the standard testing package. If you like BDD, Goconvey use scopes to define fixtures and a reset function for teardown.

    3. You can use factory and dependency injections in your testing. I think that's pretty idiomatic.

    4. A few includes Goconvey, Ginkgo and Testify They all have pros and cons of their own. The first two often end up with too many nested scopes, but Goconvey has a great browser-based real-time testing server which can be used with Go standard testing.

    Since there's no global variables/functions in Go, you might design your project in interface-delegate pattern to help with importing functions cross packages and avoiding cyclic imports when dealing with cross-package testing.

    mypackage
    
    type DBOptions struct {
            Name, Credentials string
    }
    
    func aFunc(db *sql.DB) error {
            // do something
            return nil
    }
    
    func bFunc(db *sql.DB) int, error {
            // do something
            return 0, nil
    }
    
    func establishConn(opts *DBOptions) (*sql.DB, error) {
            db, err := sql.Open(opts.Name, opts.Credentials)
            if err != nil {
                    return nil, err
            }
            return db, nil
    }
    
    func destroyConn(conn *sql.DB) {
            conn.Close()
    }
    
    // test file
    mypackage 
    
    import "testing"
    
    var myOpt = &DBOptions{
            Name: "mysql", 
            Credentials: "user:password@tcp(127.0.0.1:3306)/hello",
    }
    
    var conn, _ = establishConn(myOpt)
    
    func TestAFunc(t *testing.T) {
            err := aFunc(conn)
    
            if err != nil  {
                    t.Error(err)
            }
    }
    
    func TestBFunc(t *testing.T) {
            err := aFunc(conn)
    
            if err != nil  {
                    t.Error(err)
            }
    }
    
    // use `conn` in other tests ...
    
    destroyConn(conn)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 为什么我按照电路图做出的仿真和实物都不能使用
  • ¥15 mars2d在vue3中的引入问题
  • ¥50 h5唤醒支付宝并跳转至向小荷包转账界面
  • ¥15 算法题:数的划分,用记忆化DFS做WA求调
  • ¥15 chatglm-6b应用到django项目中,模型加载失败
  • ¥15 CreateBitmapFromWicBitmap内存释放问题。
  • ¥30 win c++ socket
  • ¥15 C# datagridview 栏位进度
  • ¥15 vue3页面el-table页面数据过多
  • ¥100 vue3中融入gRPC-web