Home > Mobile >  Problem writing a unit test using gorm and sql-mock
Problem writing a unit test using gorm and sql-mock

Time:01-21

this is my funckion using package testing, gorm and sql-mock:

func Test_Create(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Errorf("Failed to open mock sql db, got error: %v", err)
    }
    if db == nil {
        t.Error("db is null")
    }
    if mock == nil {
        t.Error("mock is null")
    }
    defer db.Close()

    pDb, err := gorm.Open(postgres.New(postgres.Config{
        PreferSimpleProtocol: false,
        DriverName:           "postgres",
        Conn:                 db,
    }))
    if err != nil {
        t.Fatalf("gorm postgres fatal: %v", err)
    }
    student := Student{
        ID:   12345,
        Name: "Test user",
    }

    mock.ExpectBegin()
    mock.ExpectExec(regexp.QuoteMeta(`INSERT INTO "students" ("id","name") VALUES ($1,$2) RETURNING "id"`)).WithArgs(student.ID, student.Name).WillReturnResult(sqlmock.NewResult(student.ID, 1))
    mock.ExpectCommit()

    err = pDb.Create(student).Error
    if err != nil {
        t.Error("error:", err)
    }
}

I don't understand why I have an error creating a unit test as in the example below, can anyone help?

CodePudding user response:

and this is the output in the console:

2023/01/21 12:01:09 [31;1mf:/.../.../.../store_test.go:53 [35;1mcall to Query 'INSERT INTO "students" ("name","id") VALUES ($1,$2) RETURNING "id"' with args [{Name: Ordinal:1 Value:Test user} {Name: Ordinal:2 Value:12345}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
  - matches sql: 'INSERT INTO "students" \("id","name"\) VALUES \(\$1,\$2\) RETURNING "id"'
  - is with arguments:
    0 - 12345
    1 - Test user
  - should return Result having:
      LastInsertId: 12345
      RowsAffected: 1; call to Rollback transaction, was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
  - matches sql: 'INSERT INTO "students" \("id","name"\) VALUES \(\$1,\$2\) RETURNING "id"'
  - is with arguments:
    0 - 12345
    1 - Test user
  - should return Result having:
      LastInsertId: 12345
      RowsAffected: 1
[0m[33m[0.566ms] [34;1m[rows:0][0m INSERT INTO "students" ("name","id") VALUES ('Test user',12345) RETURNING "id"
--- FAIL: Test_Create (0.00s)
    f:\projects\stockband_api\store\store_test.go:55: error: call to Query 'INSERT INTO "students" ("name","id") VALUES ($1,$2) RETURNING "id"' with args [{Name: Ordinal:1 Value:Test user} {Name: Ordinal:2 Value:12345}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
          - matches sql: 'INSERT INTO "students" \("id","name"\) VALUES \(\$1,\$2\) RETURNING "id"'
          - is with arguments:
            0 - 12345
            1 - Test user
          - should return Result having:
              LastInsertId: 12345
              RowsAffected: 1; call to Rollback transaction, was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
          - matches sql: 'INSERT INTO "students" \("id","name"\) VALUES \(\$1,\$2\) RETURNING "id"'
          - is with arguments:
            0 - 12345
            1 - Test user
          - should return Result having:
              LastInsertId: 12345
              RowsAffected: 1
FAIL
FAIL    github.com/.../.../store    0.732s
FAIL

CodePudding user response:

okay, I've already solved the problem. here's the working func:

func Test_Create(t *testing.T) {
    db, mock, err := sqlmock.New()
    if err != nil {
        t.Errorf("Failed to open mock sql db, got error: %v", err)
    }
    if db == nil {
        t.Error("db is null")
    }
    if mock == nil {
        t.Error("mock is null")
    }
    defer db.Close()

    dialector := postgres.New(postgres.Config{
        DSN:                  "sqlmock_db_0",
        DriverName:           "postgres",
        Conn:                 db,
        PreferSimpleProtocol: true,
    })

    pDb, err := gorm.Open(dialector, &gorm.Config{})
    if err != nil {
        t.Fatalf("gorm postgres fatal: %v", err)
    }
    student := Student{
        ID:   12345,
        Name: "Test user",
    }

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

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

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