DATA-DOG / go-sqlmock

Sql mock driver for golang to test database interactions
Other
6.16k stars 407 forks source link

Getting sql: database is closed Error while executing queries for unit testing with sqlmock and golang #271

Closed roshandcoo7 closed 3 years ago

roshandcoo7 commented 3 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
var mock sqlmock.Sqlmock

func Init() {
    db, mockdb, _ := sqlmock.New()
    defer db.Close()

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

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

func TestAddStudentEntriesSuccess(t *testing.T) {

    Init()

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

    args := []models.StudentDbEntry{
        {
            RegisterID:     1,
            StudentID:      1,
            Fee:            decimal.NewFromInt(100),
            AdmissionDate:  "10-20-2015",
        },
        {
            RegisterID:     2,
            StudentID:      3,
            Fee:            decimal.NewFromInt(100),
            AdmissionDate:  "10-21-2015",
        },
    }

    prep := mock.ExpectPrepare(query)
    prep.ExpectExec().WithArgs(args).WillReturnResult(sqlmock.NewResult(0, 0))

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

}

However, the tests are failing. I am gettingsql: database is closed 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. How to solve this?

Blackheart8788 commented 2 years ago

Hi, there hope you are well.

Would you mind telling me how did you solve it? I'm having the same issue.