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 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图
  • ¥30 乘子法解约束最优化问题的matlab代码文件,最好有matlab代码文件
  • ¥15 写论文,需要数据支撑
  • ¥15 identifier of an instance of 类 was altered from xx to xx错误
  • ¥100 反编译微信小游戏求指导
  • ¥15 docker模式webrtc-streamer 无法播放公网rtsp