DATA-DOG / go-sqlmock

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

Getting unexpected error while executing queries for unit testing with sqlmock and golang #272

Closed roshandcoo7 closed 2 years ago

roshandcoo7 commented 2 years ago

I have the following function that takes a slice of type SchoolDbEntry and bulk inserts it into a DB.

  type SchoolRegistry struct {
        Conn         *sqlx.DB
    }

    insertStudentEntry = `insert into StudentEntries (registerId, studentId, fee, admissionDate) values (:registerId, :studentId, :fee, :admissionDate)`

    func (s *SchoolRegistry) AddStudentEntries(ctx context.Context, entry []StudentDbEntry) error {
        requestHeaders := helper.FetchHeaders(ctx)

        query, args, err := sqlx.Named(insertStudentEntry, entry)
        if err != nil {
            return exception.DBInternalError
        }

        _, err = s.Conn.Exec(query, args...)
        if err != nil {
            return cutomModels.NewError(err.Error()
        }

        return nil
    }

I am trying to test this using sqlmock using the following functions

    var repo *SchoolRegistry

    func TestAddStudentEntriesSuccess(t *testing.T) {

         db, mock, err := sqlmock.New()
     if err != nil {
            t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
     }

     sqlxDb := sqlx.NewDb(db, "sqlmock")

     defer sqlxDb.Close()

     repo = &SchoolRegistry{sqlxDb}
     if err := logger.Init(logLevel, logTimeFormat); err != nil {
        fmt.Printf("failed to initialize logger: %v", err)
     }

        query := `insert into StudentEntries (registerId, studentId, fee, admissionDate) values (:registerId, :studentId, :fee, :admissionDate)`

        args := []models.StudentDbEntry{
            {
                RegisterID:     1,
                StudentID:      1,
                Fee:            "100",
                AdmissionDate:  "10-20-2015",
            },
        }

        prep := mock.ExpectPrepare(query)
        prep.ExpectExec().WithArgs(1,1,"100","10-20-2015").WillReturnResult(sqlmock.NewResult(0, 0))

        err := repo.AddStudentEntries(helper.FetchTestContext(), args)
        assert.NoError(t, err)

    }

However, the tests are failing. I am getting

    call to ExecQuery 'insert into StudentEntries (registerId, studentId, fee, admissionDate) values (?, ?, ?, ?)' with args [{Name: Ordinal:1 Value:1} {Name: Ordinal:2 Value:1} {Name: Ordinal:3 Value:"100"} {Name: Ordinal:4 Value:"10-20-2015"}], was not expected, next expectation is: ExpectedPrepare => expecting Prepare statement which:
                                  - matches sql: 'insert into StudentEntries (registerId, studentId, fee, admissionDate) values (:registerId, :studentId, :fee, :admissionDate)' 

error when no errors are expected ( that is, after this line : _, err = s.Conn.Exec(query, args...) ). The function works fine when I tested it as a part of the actual code. The issue is just with the unit testing.

dolmen commented 2 years ago

Please post some example code working on the Go Playground. Here is a template.

Ghvstcode commented 2 years ago

Hi, This thread has been inactive for a while so I will be closing this.