bulkinserter_test.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package sqlx
  2. import (
  3. "database/sql"
  4. "strconv"
  5. "testing"
  6. "github.com/DATA-DOG/go-sqlmock"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/tal-tech/go-zero/core/logx"
  9. )
  10. type mockedConn struct {
  11. query string
  12. args []interface{}
  13. }
  14. func (c *mockedConn) Exec(query string, args ...interface{}) (sql.Result, error) {
  15. c.query = query
  16. c.args = args
  17. return nil, nil
  18. }
  19. func (c *mockedConn) Prepare(query string) (StmtSession, error) {
  20. panic("should not called")
  21. }
  22. func (c *mockedConn) QueryRow(v interface{}, query string, args ...interface{}) error {
  23. panic("should not called")
  24. }
  25. func (c *mockedConn) QueryRowPartial(v interface{}, query string, args ...interface{}) error {
  26. panic("should not called")
  27. }
  28. func (c *mockedConn) QueryRows(v interface{}, query string, args ...interface{}) error {
  29. panic("should not called")
  30. }
  31. func (c *mockedConn) QueryRowsPartial(v interface{}, query string, args ...interface{}) error {
  32. panic("should not called")
  33. }
  34. func (c *mockedConn) Transact(func(session Session) error) error {
  35. panic("should not called")
  36. }
  37. func TestBulkInserter(t *testing.T) {
  38. runSqlTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
  39. var conn mockedConn
  40. inserter, err := NewBulkInserter(&conn, `INSERT INTO classroom_dau(classroom, user, count) VALUES(?, ?, ?)`)
  41. assert.Nil(t, err)
  42. for i := 0; i < 5; i++ {
  43. assert.Nil(t, inserter.Insert("class_"+strconv.Itoa(i), "user_"+strconv.Itoa(i), i))
  44. }
  45. inserter.Flush()
  46. assert.Equal(t, `INSERT INTO classroom_dau(classroom, user, count) VALUES `+
  47. `('class_0', 'user_0', 0), ('class_1', 'user_1', 1), ('class_2', 'user_2', 2), `+
  48. `('class_3', 'user_3', 3), ('class_4', 'user_4', 4)`,
  49. conn.query)
  50. assert.Nil(t, conn.args)
  51. })
  52. }
  53. func TestBulkInserterSuffix(t *testing.T) {
  54. runSqlTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
  55. var conn mockedConn
  56. inserter, err := NewBulkInserter(&conn, `INSERT INTO classroom_dau(classroom, user, count) VALUES`+
  57. `(?, ?, ?) ON DUPLICATE KEY UPDATE is_overtime=VALUES(is_overtime)`)
  58. assert.Nil(t, err)
  59. for i := 0; i < 5; i++ {
  60. assert.Nil(t, inserter.Insert("class_"+strconv.Itoa(i), "user_"+strconv.Itoa(i), i))
  61. }
  62. inserter.Flush()
  63. assert.Equal(t, `INSERT INTO classroom_dau(classroom, user, count) VALUES `+
  64. `('class_0', 'user_0', 0), ('class_1', 'user_1', 1), ('class_2', 'user_2', 2), `+
  65. `('class_3', 'user_3', 3), ('class_4', 'user_4', 4) ON DUPLICATE KEY UPDATE is_overtime=VALUES(is_overtime)`,
  66. conn.query)
  67. assert.Nil(t, conn.args)
  68. })
  69. }
  70. func runSqlTest(t *testing.T, fn func(db *sql.DB, mock sqlmock.Sqlmock)) {
  71. logx.Disable()
  72. db, mock, err := sqlmock.New()
  73. if err != nil {
  74. t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
  75. }
  76. defer db.Close()
  77. fn(db, mock)
  78. if err := mock.ExpectationsWereMet(); err != nil {
  79. t.Errorf("there were unfulfilled expectations: %s", err)
  80. }
  81. }