0

I'm trying to mock the following function. I'm struggling to get it to test the rows.next() return.

    func (u *userRepository) GetList(idClient int) ([]UserPublic, rest_errors.RestErr) {

    stmt, err := u.client.Prepare(queryGetUserList)
    if err != nil {
        logger.Error("Error when trying to prepare get user list statement", err)
        return nil, rest_errors.NewInternalServerError("Error when tying to get user list", errors.New("database error"))
    }
    defer stmt.Close()

    var userList []UserPublic
    var user UserPublic
    rows, errStmt := stmt.Query(idClient)

    if errStmt != nil {
        logger.Error("Error when trying to query the user list", errStmt)
        return nil, rest_errors.NewInternalServerError("Error when tying to get the user list", errors.New("database error"))
    }

    for rows.Next() {
        if getErr := rows.Scan(&user.Id, &user.Name, &user.FirstSurname, &user.SecondSurname, &user.Email, &user.BirthDate, &user.identityNumberSql, &user.clinicalNumberSql, &user.cardSql, &user.phoneNumberSql, &user.Role, &user.DateCreated); getErr != nil {
            logger.Error("Error when trying to get user list", getErr)
            return nil, mysql_utils.ParseError(getErr)
        }
        userList = append(userList, user)
    }

    return userList, nil
}

This is my test case:

func TestUserGetListErrorScanRows (t *testing.T) {
    db, mock, err = getMockDB(t)
    defer db.Close()

    s := NewUserDaoMySQL(db)

    t.Run("Error scanning rows", func(t *testing.T) {
        rows := sqlmock.NewRows([]string{"id", "name", "first_surname", "second_surname", "email", "birth_date", "identity_number", "clinical_number", "card", "phone_number", "role", "date_created"}).AddRow(0, user.Name, user.FirstSurname, user.SecondSurname, user.Email, user.BirthDate, user.IdentityNumber, user.ClinicalNumber, user.Card, user.PhoneNumber, user.Role, user.DateCreated).
            RowError(1, fmt.Errorf("row error"))
        mock.ExpectPrepare("SELECT (.+) FROM user").ExpectQuery().WillReturnRows(rows)

        rs, errDb := db.Query("SELECT (.+) FROM user")
        fmt.Println(errDb)
        defer rs.Close()

        for rs.Next() {
            u := UserPublic{
                Id:                 0,
                Name:               "",
                FirstSurname:       "",
                SecondSurname:      "",
                Email:              "",
                BirthDate:          "",
                IdentityNumber:     "",
                ClinicalNumber:     "",
                IdInsuranceCompany: 0,
                Card:               "",
                IdClient:           0,
                PhoneNumber:        "",
                Role:               0,
                DateCreated:        "",
            }

            err := rs.Scan(&u.Id, &u.Name, &u.FirstSurname, &u.SecondSurname, &u.Email, &u.BirthDate, &u.IdentityNumber, &u.ClinicalNumber, &u.Card, &u.PhoneNumber, &u.Role, &u.DateCreated)
            if err != nil {
                fmt.Println("got scan error:", err)
                break
            }
        }

        id, err := s.GetList(int(user.IdClient))

        assert.NotNil(t, err)
        assert.Nil(t, id)
    })
}

The error I'm getting is:

call to Query 'SELECT (.+) FROM user' with args [], was not expected, next expectation is: ExpectedPrepare => expecting Prepare statement which:

  • matches sql: 'SELECT (.+) FROM user'

Any idea where the error might be?

Antoni
  • 75
  • 10
  • does sqlmock have a `.ExpectQuery()` method ? – LeGEC Mar 11 '21 at 19:59
  • Yes, I am using it mock.ExpectPrepare("SELECT (.+) FROM user").ExpectQuery() – Antoni Mar 11 '21 at 21:21
  • What's the first call to `db.Query()` in your test function for ? – LeGEC Mar 11 '21 at 21:47
  • I've read it's needed to be able to mock the row scan – Antoni Mar 12 '21 at 06:58
  • ok (I haven't read how sqlmock works, I'll take your word for it) ; but in that case, shouldn't your expectations start with a `.ExcpectQuery()` ? – LeGEC Mar 12 '21 at 07:44
  • If I remove the ExpectPrepare and go directly to ExpectQuery I get this error: {"level":"error","time":"2021-03-12T11:29:22.942+0100","msg":"Error when trying to prepare get user list statement","error":"all expectations were already fulfilled, call to Prepare 'SELECT id, name, first_surname, second_surname, email, birth_date, identity_number, clinical_number, card, phone_number, role, date_created FROM user WHERE id_client=?' query was not expected"} – Antoni Mar 12 '21 at 10:30
  • read the code of your test : what sequence of actions is `.Expect`ed ? – LeGEC Mar 12 '21 at 10:49
  • The problem seems to be in the rows.Scan method. I'll just leave it without coverage since I can't find any example. – Antoni Mar 12 '21 at 15:20

0 Answers0