When unit testing I mock gorm using sqlmock. But when running all initial setup are fine but error happen when the actual query and testing query matches. I have given below all codes.
user.go
func (r *users) GetUserByID(userID uint) (*domain.User, *errors.RestErr) {
var resp domain.User
res := r.DB.Model(&domain.User{}).Where("id = ?", userID).First(&resp)
if res.RowsAffected == 0 {
logger.Error("error occurred when getting user by user id", res.Error)
return nil, errors.NewNotFoundError(errors.ErrRecordNotFound)
}
return &resp, nil
}
Mock
user_test.go
type Suite struct {
suite.Suite
DB *gorm.DB
mock sqlmock.Sqlmock
db *sql.DB
err error
repository repository.IUsers
}
func (s *Suite) SetupSuite() {
s.db, s.mock, s.err = sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
require.NoError(s.T(), s.err)
dialector := mysql.New(mysql.Config{
DSN: "sqlmock_db_0",
DriverName: "mysql",
Conn: s.db,
SkipInitializeWithVersion: true,
})
s.DB, s.err = gorm.Open(dialector, &gorm.Config{})
require.NoError(s.T(), s.err)
s.repository = impl.NewMySqlUsersRepository(s.DB)
}
func (s *Suite) AfterTest(_, _ string) {
require.NoError(s.T(), s.mock.ExpectationsWereMet())
}
func TestInit(t *testing.T) {
suite.Run(t, new(Suite))
}
// .................Start Testing....................
func (s *Suite) Test_repository_Get() {
var (
id = uint(1)
user_name = "user-name"
fast_name = "fast-name"
)
s.mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "users" WHERE (id = $1) ORDER BY "users"."id" LIMIT 1`)).
WithArgs(uint(id)).
WillReturnRows(sqlmock.NewRows([]string{"id", "user_name", "fast_name"}).
AddRow(uint(id), user_name, fast_name))
res, _ := s.repository.GetUserByID(uint(id))
require.Nil(s.T(), deep.Equal(&domain.User{ID: uint(id), UserName: user_name, LastName: fast_name}, res))
}
when I execute res, _ := s.repository.GetUserByID(uint(id)) this line it goes user.go file. Here in sql query line Getting error Like this given below .
actual sql: "SELECT * FROM `users` WHERE id = ? ORDER BY `users`.`id` LIMIT 1"
does not equal to expected "SELECT \* FROM "users" WHERE \(id = \$1\) ORDER BY "users"\."id" LIMIT 1"
=> expecting Query, QueryContext or QueryRow which:
- matches sql: 'SELECT \* FROM "users" WHERE \(id = \$1\) ORDER BY "users"\."id" LIMIT 1'
- is with arguments:
0 - 1
- should return rows:
row 0 - [1 user-name fast-name]
What is the issue here?
"SELECT * FROM `users` WHERE id = ? ORDER BY `users`.`id`LIMIT 1"` is not equal to"SELECT \* FROM "users" WHERE \(id = \$1\) ORDER BY "users"\."id" LIMIT 1". Where the first query is what the mock driver received as input from gorm (ieactual sql), and the second query is what you have written as expectation. Your expectation is wrong.