DATA-DOG / go-sqlmock

Sql mock driver for golang to test database interactions
Other
6.02k stars 406 forks source link

go-sqlmock with gorm #252

Closed majidbl closed 2 months ago

majidbl commented 3 years ago

how i can use go-sqlmock for newer version of gorm in my project

Anonyma commented 3 years ago

What is the question here? What errors are you getting?

I haven't had any issues while using gorm.io/gorm v1.20.11 (gORM v2) with go-sqlmock v1.5.0

majidbl commented 3 years ago

my error is : call to ExecQuery 'INSERT INTO "users" ("id","user_name","pass_word","email","role","name","created_at","updated_at") VALUES ($1,$2,$3,$4,$5,$6,$7,$8)' with args [{Name: Ordinal:1 Value:a8813f4a-bd82-4dd2-bdd9-fbcf0aa7787f} {Name: Ordinal:2 Value:test} {Name: Ordinal:3 Value:12345} {Name: Ordinal:4 Value:testemail} {Name: Ordinal:5 Value:admin} {Name: Ordinal:6 Value:test} {Name: Ordinal:7 Value:2020-11-18 16:36:03.948311091 +0330 +0330 m=+0.005700519} {Name: Ordinal:8 Value:2020-11-18 16:36:03.94831117 +0330 +0330 m=+0.005700600}] was not expected; call to Rollback transaction was not expected [0.300ms] [rows:0] INSERT INTO "users" ("id","user_name","pass_word","email","role","name","created_at","updated_at") VALUES ('a8813f4a-bd82-4dd2-bdd9-fbcf0aa7787f','test','12345','testemail','admin','test','2020-11-18 16:36:03.948','2020-11-18 16:36:03.948') --- FAIL: TestSignUp (0.00s) postgersql_test.go:96: Failed to insert to gorm db, got error: call to ExecQuery 'INSERT INTO "users" ("id","user_name","pass_word","email","role","name","created_at","updated_at") VALUES ($1,$2,$3,$4,$5,$6,$7,$8)' with args [{Name: Ordinal:1 Value:a8813f4a-bd82-4dd2-bdd9-fbcf0aa7787f} {Name: Ordinal:2 Value:test} {Name: Ordinal:3 Value:12345} {Name: Ordinal:4 Value:testemail} {Name: Ordinal:5 Value:admin} {Name: Ordinal:6 Value:test} {Name: Ordinal:7 Value:2020-11-18 16:36:03.948311091 +0330 +0330 m=+0.005700519} {Name: Ordinal:8 Value:2020-11-18 16:36:03.94831117 +0330 +0330 m=+0.005700600}] was not expected; call to Rollback transaction was not expected postgersql_test.go:101: Failed to meet expectations, got error: there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:

majidbl commented 3 years ago

every thing is ok but test failed

l3pp4rd commented 3 years ago

I think your expectation is wrong, instead of ExpectQuery seems like there is ExpectExec needed. Update and insert statements are not Query

majidbl commented 3 years ago

all thing same like before, nothing changed

Anonyma commented 3 years ago

Either assert an exact match of the arguments you are passing or use sqlmock.AnyArg() (passing as many sqlmock.AnyArg() as arguments you have)

joaquinicolas commented 3 years ago

Check your expectation. Be sure you're expecting what your statement is returning and, if you haven't done yet, you might want to see GORM debugger by adding ExpectBegin() and ExpectCommit().

majidbl commented 3 years ago
package main

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

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

type Student struct {
    //*gorm.Model
    Name string
    ID string
}
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)
    }
}
majidbl commented 3 years ago

that is my example source

valtab commented 2 years ago

Link GORM related issue which was resolved by GORM author gorm v2.0 unit testing with sqlmock: https://github.com/go-gorm/gorm/issues/3565