model_test.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. package model
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "fmt"
  6. "testing"
  7. "time"
  8. "git.i2edu.net/i2/go-zero/core/stores/cache"
  9. "git.i2edu.net/i2/go-zero/core/stores/redis"
  10. "git.i2edu.net/i2/go-zero/core/stores/redis/redistest"
  11. mocksql "git.i2edu.net/i2/go-zero/tools/goctl/model/sql/test"
  12. "github.com/DATA-DOG/go-sqlmock"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func TestStudentModel(t *testing.T) {
  16. var (
  17. testTimeValue = time.Now()
  18. testTable = "`student`"
  19. testUpdateName = "gozero1"
  20. testRowsAffected int64 = 1
  21. testInsertId int64 = 1
  22. class = "一年级1班"
  23. )
  24. var data Student
  25. data.Id = testInsertId
  26. data.Class = class
  27. data.Name = "gozero"
  28. data.Age = sql.NullInt64{
  29. Int64: 1,
  30. Valid: true,
  31. }
  32. data.Score = sql.NullFloat64{
  33. Float64: 100,
  34. Valid: true,
  35. }
  36. data.CreateTime = testTimeValue
  37. data.UpdateTime = sql.NullTime{
  38. Time: testTimeValue,
  39. Valid: true,
  40. }
  41. err := mockStudent(func(mock sqlmock.Sqlmock) {
  42. mock.ExpectExec(fmt.Sprintf("insert into %s", testTable)).
  43. WithArgs(data.Class, data.Name, data.Age, data.Score).
  44. WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  45. }, func(m StudentModel, redis *redis.Redis) {
  46. r, err := m.Insert(data)
  47. assert.Nil(t, err)
  48. lastInsertId, err := r.LastInsertId()
  49. assert.Nil(t, err)
  50. assert.Equal(t, testInsertId, lastInsertId)
  51. rowsAffected, err := r.RowsAffected()
  52. assert.Nil(t, err)
  53. assert.Equal(t, testRowsAffected, rowsAffected)
  54. })
  55. assert.Nil(t, err)
  56. err = mockStudent(func(mock sqlmock.Sqlmock) {
  57. mock.ExpectQuery(fmt.Sprintf("select (.+) from %s", testTable)).
  58. WithArgs(testInsertId).
  59. WillReturnRows(sqlmock.NewRows([]string{"id", "class", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertId, data.Class, data.Name, data.Age, data.Score, testTimeValue, testTimeValue))
  60. }, func(m StudentModel, redis *redis.Redis) {
  61. result, err := m.FindOne(testInsertId)
  62. assert.Nil(t, err)
  63. assert.Equal(t, *result, data)
  64. var resp Student
  65. val, err := redis.Get(fmt.Sprintf("%s%v", cacheStudentIdPrefix, testInsertId))
  66. assert.Nil(t, err)
  67. err = json.Unmarshal([]byte(val), &resp)
  68. assert.Nil(t, err)
  69. assert.Equal(t, resp.Name, data.Name)
  70. })
  71. assert.Nil(t, err)
  72. err = mockStudent(func(mock sqlmock.Sqlmock) {
  73. mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(data.Class, testUpdateName, data.Age, data.Score, testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  74. }, func(m StudentModel, redis *redis.Redis) {
  75. data.Name = testUpdateName
  76. err := m.Update(data)
  77. assert.Nil(t, err)
  78. val, err := redis.Get(fmt.Sprintf("%s%v", cacheStudentIdPrefix, testInsertId))
  79. assert.Nil(t, err)
  80. assert.Equal(t, "", val)
  81. })
  82. assert.Nil(t, err)
  83. data.Name = testUpdateName
  84. err = mockStudent(func(mock sqlmock.Sqlmock) {
  85. mock.ExpectQuery(fmt.Sprintf("select (.+) from %s ", testTable)).
  86. WithArgs(testInsertId).
  87. WillReturnRows(sqlmock.NewRows([]string{"id", "class", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertId, data.Class, data.Name, data.Age, data.Score, testTimeValue, testTimeValue))
  88. }, func(m StudentModel, redis *redis.Redis) {
  89. result, err := m.FindOne(testInsertId)
  90. assert.Nil(t, err)
  91. assert.Equal(t, *result, data)
  92. var resp Student
  93. val, err := redis.Get(fmt.Sprintf("%s%v", cacheStudentIdPrefix, testInsertId))
  94. assert.Nil(t, err)
  95. err = json.Unmarshal([]byte(val), &resp)
  96. assert.Nil(t, err)
  97. assert.Equal(t, testUpdateName, data.Name)
  98. })
  99. assert.Nil(t, err)
  100. err = mockStudent(func(mock sqlmock.Sqlmock) {
  101. mock.ExpectQuery(fmt.Sprintf("select (.+) from %s ", testTable)).
  102. WithArgs(class, testUpdateName).
  103. WillReturnRows(sqlmock.NewRows([]string{"id", "class", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertId, data.Class, data.Name, data.Age, data.Score, testTimeValue, testTimeValue))
  104. }, func(m StudentModel, redis *redis.Redis) {
  105. result, err := m.FindOneByClassName(class, testUpdateName)
  106. assert.Nil(t, err)
  107. assert.Equal(t, *result, data)
  108. val, err := redis.Get(fmt.Sprintf("%s%v%v", cacheStudentClassNamePrefix, class, testUpdateName))
  109. assert.Nil(t, err)
  110. assert.Equal(t, "1", val)
  111. })
  112. assert.Nil(t, err)
  113. err = mockStudent(func(mock sqlmock.Sqlmock) {
  114. mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  115. }, func(m StudentModel, redis *redis.Redis) {
  116. err = m.Delete(testInsertId, class, testUpdateName)
  117. assert.Nil(t, err)
  118. val, err := redis.Get(fmt.Sprintf("%s%v", cacheStudentIdPrefix, testInsertId))
  119. assert.Nil(t, err)
  120. assert.Equal(t, "", val)
  121. val, err = redis.Get(fmt.Sprintf("%s%v%v", cacheStudentClassNamePrefix, class, testUpdateName))
  122. assert.Nil(t, err)
  123. assert.Equal(t, "", val)
  124. })
  125. assert.Nil(t, err)
  126. }
  127. func TestUserModel(t *testing.T) {
  128. var (
  129. testTimeValue = time.Now()
  130. testTable = "`user`"
  131. testUpdateName = "gozero1"
  132. testUser = "gozero"
  133. testPassword = "test"
  134. testMobile = "test_mobile"
  135. testGender = "男"
  136. testNickname = "test_nickname"
  137. testRowsAffected int64 = 1
  138. testInsertId int64 = 1
  139. )
  140. var data User
  141. data.ID = testInsertId
  142. data.User = testUser
  143. data.Name = "gozero"
  144. data.Password = testPassword
  145. data.Mobile = testMobile
  146. data.Gender = testGender
  147. data.Nickname = testNickname
  148. data.CreateTime = testTimeValue
  149. data.UpdateTime = testTimeValue
  150. err := mockUser(func(mock sqlmock.Sqlmock) {
  151. mock.ExpectExec(fmt.Sprintf("insert into %s", testTable)).
  152. WithArgs(data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname).
  153. WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  154. }, func(m UserModel) {
  155. r, err := m.Insert(data)
  156. assert.Nil(t, err)
  157. lastInsertId, err := r.LastInsertId()
  158. assert.Nil(t, err)
  159. assert.Equal(t, testInsertId, lastInsertId)
  160. rowsAffected, err := r.RowsAffected()
  161. assert.Nil(t, err)
  162. assert.Equal(t, testRowsAffected, rowsAffected)
  163. })
  164. assert.Nil(t, err)
  165. err = mockUser(func(mock sqlmock.Sqlmock) {
  166. mock.ExpectQuery(fmt.Sprintf("select (.+) from %s", testTable)).
  167. WithArgs(testInsertId).
  168. WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertId, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue))
  169. }, func(m UserModel) {
  170. result, err := m.FindOne(testInsertId)
  171. assert.Nil(t, err)
  172. assert.Equal(t, *result, data)
  173. })
  174. assert.Nil(t, err)
  175. err = mockUser(func(mock sqlmock.Sqlmock) {
  176. mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(data.User, testUpdateName, data.Password, data.Mobile, data.Gender, data.Nickname, testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  177. }, func(m UserModel) {
  178. data.Name = testUpdateName
  179. err := m.Update(data)
  180. assert.Nil(t, err)
  181. })
  182. assert.Nil(t, err)
  183. err = mockUser(func(mock sqlmock.Sqlmock) {
  184. mock.ExpectQuery(fmt.Sprintf("select (.+) from %s ", testTable)).
  185. WithArgs(testInsertId).
  186. WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertId, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue))
  187. }, func(m UserModel) {
  188. result, err := m.FindOne(testInsertId)
  189. assert.Nil(t, err)
  190. assert.Equal(t, *result, data)
  191. })
  192. assert.Nil(t, err)
  193. err = mockUser(func(mock sqlmock.Sqlmock) {
  194. mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected))
  195. }, func(m UserModel) {
  196. err := m.Delete(testInsertId)
  197. assert.Nil(t, err)
  198. })
  199. assert.Nil(t, err)
  200. }
  201. // with cache
  202. func mockStudent(mockFn func(mock sqlmock.Sqlmock), fn func(m StudentModel, r *redis.Redis)) error {
  203. db, mock, err := sqlmock.New()
  204. if err != nil {
  205. return err
  206. }
  207. defer db.Close()
  208. mock.ExpectBegin()
  209. mockFn(mock)
  210. mock.ExpectCommit()
  211. conn := mocksql.NewMockConn(db)
  212. r, clean, err := redistest.CreateRedis()
  213. if err != nil {
  214. return err
  215. }
  216. defer clean()
  217. m := NewStudentModel(conn, cache.CacheConf{
  218. {
  219. RedisConf: redis.RedisConf{
  220. Host: r.Addr,
  221. Type: "node",
  222. },
  223. Weight: 100,
  224. },
  225. })
  226. mock.ExpectBegin()
  227. fn(m, r)
  228. mock.ExpectCommit()
  229. return nil
  230. }
  231. // without cache
  232. func mockUser(mockFn func(mock sqlmock.Sqlmock), fn func(m UserModel)) error {
  233. db, mock, err := sqlmock.New()
  234. if err != nil {
  235. return err
  236. }
  237. defer db.Close()
  238. mock.ExpectBegin()
  239. mockFn(mock)
  240. mock.ExpectCommit()
  241. conn := mocksql.NewMockConn(db)
  242. m := NewUserModel(conn)
  243. fn(m)
  244. return nil
  245. }