6

I'm using Gorm with the postgresql driver. I try to mock a database insert with go-sqlmock:

type Test struct {
    FirstName string `json:"first_name"`
}

func (db *DB) CreateTest() (*Test, error) {
    test := Test{"c"}
    if result := db.Create(&test); result.Error != nil {
        return nil, result.Error
    }

    return &test, nil
}


func TestCreateUser(t *testing.T) {
    _, mock, _ := sqlmock.NewWithDSN("sqlmock_db_0")

    mockedGorm, _ := gorm.Open("sqlmock", "sqlmock_db_0")
    defer mockedGorm.Close()
    myDB := &DB{mockedGorm}

    mock.ExpectExec("INSERT INTO test").WithArgs("c").WillReturnResult(sqlmock.NewResult(1, 1))
    myDB.Exec("INSERT INTO test(first_name) VALUES (?)", "c")


    if _, err := myDB.CreateTest(); err != nil {
        t.Errorf("error was not expected: %s", err)
    }

    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("there were unfulfilled expectations: %s", err)
    }
}

Unfortunately, this gives me an error:

error was not expected: all expectations were already fulfilled, call to database transaction Begin was not expected

How do I test an insert with gorm, postgresql and sql-mock properly?

1
  • 2
    The error message is pretty explicit. "Begin was not expected". You didn't tell it to expect a Begin, which GORM is obviously executing. What help do you need? Commented Feb 10, 2020 at 19:03

1 Answer 1

3

There were a couple of issues with my code:

1) As @flimzy pointed out rightfully, there has to be a ExpectBegin() (and ExpectCommit()) statement. This gets more obvious if one turns on the GORM debugger that shows what exactly GORM is doing.

2) ExpectExec("INSERT INTO test").WithArgs("c") does quite obviously not match myDB.Exec("INSERT INTO test(first_name) VALUES (?)", "c")

3) One has to escape the statement, as go-sqlmock takes a regex, here Go's https://godoc.org/regexp#QuoteMeta comes in handy.

Working code:

mock.ExpectBegin()
mock.ExpectExec(regexp.QuoteMeta("INSERT INTO \"tests\" (\"first_name\") VALUES (?)")).WithArgs("c").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.