简体   繁体   中英

Can I test queries in goroutine with sqlmock?

I have this code in my application, I use goroutine because that queries are very slow. The code works correctly but I've been trying to test that function with sqlmock and that been having a lot of false positives and a lot of dificulties, what can I do to test those queries using sqlmock? (Obs: I've used postgres)

func(r repository) Queries(ctx context.Context) (*models.MyModel, error) {
    var users int64
    var services int64
    var sells int64

    queryReponses := make(chan *gorm.DB, 3)

    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM deposits").Find(&users)
    }()
    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM services").Find(&users)
    }()
    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM sells").Find(&users)
    }()

    for i := 0; i < 3; i += 1 {
        queryResponse := <-queryReponses
        if queryResponse.Error != nil {
            return &models.MyModel{}, fmt.Errorf(queryResponse.Error)
        }
    }

    return &models.MyModel{
        Users: users,
        Services: services,
        Sells: sells,
    }
}

You modify the same value concurrently, run your tests with a -race detector flag to detect it

 go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM deposits").Find(&users)
    }()
-    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM services").Find(&users)
+    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM services").Find(&services)
    }()
-    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM sells").Find(&users)
    }()
+    go func(){
        queryResponses <- r.db.Raw("SELECT COUNT(*) FROM sells").Find(&sells)
    }()

also for such a case the sync/errgroup is more convenient to use:

var g errgroup.Group

g.Go(func() error {
    return r.db.Raw("SELECT COUNT(*) FROM deposits").Find(&users).Error
})
g.Go(func() error {
    return r.db.Raw("SELECT COUNT(*) FROM services").Find(&services).Error
})

if err := g.Wait(); err == nil {
  return &models.MyModel{}, fmt.Errorf(queryResponse.Error)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM