gorm v2.0 unit testing with sqlmock

Created on 2 Oct 2020  Â·  8Comments  Â·  Source: go-gorm/gorm

Description

Unit testing with sqlmock works great with V1. But after updating to V2 the same test fails with following error:

/workspace/go/src/github.com/go-gorm/playground/gorm-v2-sqlmock_test.go:73 call to ExecQuery 'INSERT INTO "students" ("id","name") VALUES ($1,$2)' with args [{Name: Ordinal:1 Value:123456} {Name: Ordinal:2 Value:Test 1}] was not expected; call to Rollback transaction was not expected

I am unable to push to playground and getting permission denied. But here are the test files and also attaching the repository as a zip file.

package main

import (
    "database/sql"
    "regexp"
    "testing"

    "github.com/jinzhu/gorm"
    "gopkg.in/DATA-DOG/go-sqlmock.v1"
)

type v1Suite struct {
    db      *gorm.DB
    mock    sqlmock.Sqlmock
    student Student
}

func TestGORMV1(t *testing.T) {
    s := &v1Suite{}
    var (
        db  *sql.DB
        err error
    )

    db, s.mock, err = sqlmock.New()
    if err != nil {
        t.Errorf("Failed to open mock sql db, got error: %v", err)
    }

    if db == nil {
        t.Error("mock db is null")
    }

    if s.mock == nil {
        t.Error("sqlmock is null")
    }

    s.db, err = gorm.Open("postgres", db)
    if err != nil {
        t.Errorf("Failed to open gorm db, got error: %v", err)
    }

    if s.db == nil {
        t.Error("gorm db is null")
    }

    s.student = Student{
        ID:   "123456",
        Name: "Test 1",
    }

    defer db.Close()

    s.mock.MatchExpectationsInOrder(false)
    s.mock.ExpectBegin()

    s.mock.ExpectQuery(regexp.QuoteMeta(
        `INSERT INTO "students" ("id","name") 
                    VALUES ($1,$2) RETURNING "students"."id"`)).
        WithArgs(s.student.ID, s.student.Name).
        WillReturnRows(sqlmock.NewRows([]string{"id"}).
            AddRow(s.student.ID))

    s.mock.ExpectCommit()

    if err = s.db.Create(&s.student).Error; err != nil {
        t.Errorf("Failed to insert to gorm db, got error: %v", err)
    }

    err = s.mock.ExpectationsWereMet()
    if err != nil {
        t.Errorf("Failed to meet expectations, got error: %v", err)
    }
}

After updated to V2:

package main

import (
    "database/sql"
    "regexp"
    "testing"

    "gopkg.in/DATA-DOG/go-sqlmock.v1"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type v2Suite struct {
    db      *gorm.DB
    mock    sqlmock.Sqlmock
    student Student
}

func TestGORMV2(t *testing.T) {
    s := &v2Suite{}
    var (
        db  *sql.DB
        err error
    )

    db, s.mock, err = sqlmock.New()
    if err != nil {
        t.Errorf("Failed to open mock sql db, got error: %v", err)
    }

    if db == nil {
        t.Error("mock db is null")
    }

    if s.mock == nil {
        t.Error("sqlmock is null")
    }

    dialector := postgres.New(postgres.Config{
        DSN:                  "sqlmock_db_0",
        DriverName:           "postgres",
        Conn:                 db,
        PreferSimpleProtocol: true,
    })
    s.db, err = gorm.Open(dialector, &gorm.Config{})
    if err != nil {
        t.Errorf("Failed to open gorm v2 db, got error: %v", err)
    }

    if s.db == nil {
        t.Error("gorm db is null")
    }

    s.student = Student{
        ID:   "123456",
        Name: "Test 1",
    }

    defer db.Close()

    s.mock.MatchExpectationsInOrder(false)
    s.mock.ExpectBegin()

    s.mock.ExpectQuery(regexp.QuoteMeta(
        `INSERT INTO "students" ("id","name")
                    VALUES ($1,$2) RETURNING "students"."id"`)).
        WithArgs(s.student.ID, s.student.Name).
        WillReturnRows(sqlmock.NewRows([]string{"id"}).
            AddRow(s.student.ID))

    s.mock.ExpectCommit()

    if err = s.db.Create(&s.student).Error; err != nil {
        t.Errorf("Failed to insert to gorm db, got error: %v", err)
    }

    err = s.mock.ExpectationsWereMet()
    if err != nil {
        t.Errorf("Failed to meet expectations, got error: %v", err)
    }
}
[playground.zip](https://github.com/go-gorm/gorm/files/5319499/playground.zip)

stale missing reproduction steps

Most helpful comment

When using MySQL, you need to use SkipInitializeWithVersion: true

https://gorm.io/docs/connecting_to_the_database.html#MySQL

All 8 comments

The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 2 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨

Author,

Please check this isssue.

Thanks
Ravi Kalli

Sent from my iPhone

On Oct 4, 2020, at 1:52 PM, github-actions[bot] notifications@github.com wrote:


Closed #3565.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

@jinzhu How to mock Gorm v2 with sqlmock. Any example would be greatly helpful

Checkout connect with existing database connection, personally I don't use sqlmock for testing, use real databases.

https://gorm.io/docs/connecting_to_the_database.html#Existing-database-connection

@rkalli you could disable the default transaction https://gorm.io/docs/gorm_config.html#SkipDefaultTransaction

Checkout connect with existing database connection, personally I don't use sqlmock for testing, use real databases.

https://gorm.io/docs/connecting_to_the_database.html#Existing-database-connection

Following the steps here with sql-mock is returning this error failed to initialize database, got error all expectations were already fulfilled, call to Query 'SELECT VERSION()' with args [] was not expected

Reproducible code:

package main

import (
    "github.com/DATA-DOG/go-sqlmock"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

func main() {

    sqlDB, _, err := sqlmock.New()
    if err != nil {
        panic(err)
    }

    gormDB, err := gorm.Open(mysql.New(mysql.Config{
        Conn: sqlDB,
    }), &gorm.Config{})
    if err != nil {
        panic(err) // Error here
    }

    _ = gormDB
}

When using MySQL, you need to use SkipInitializeWithVersion: true

https://gorm.io/docs/connecting_to_the_database.html#MySQL

@jinzhu Thanks for the quick response, it's working now

Was this page helpful?
0 / 5 - 0 ratings

Related issues

superwf picture superwf  Â·  3Comments

izouxv picture izouxv  Â·  3Comments

alanyuen picture alanyuen  Â·  3Comments

corvinusy picture corvinusy  Â·  3Comments

pjebs picture pjebs  Â·  3Comments