1 package sqlmock
2
3 import (
4 "database/sql"
5 "database/sql/driver"
6 "errors"
7 "fmt"
8 "reflect"
9 "strconv"
10 "sync"
11 "testing"
12 "time"
13 )
14
15 func cancelOrder(db *sql.DB, orderID int) error {
16 tx, _ := db.Begin()
17 _, _ = tx.Query("SELECT * FROM orders {0} FOR UPDATE", orderID)
18 err := tx.Rollback()
19 if err != nil {
20 return err
21 }
22 return nil
23 }
24
25 func Example() {
26
27 db, mock, err := New()
28 if err != nil {
29 fmt.Println("error creating mock database")
30 return
31 }
32
33 columns := []string{"id", "status"}
34
35 mock.ExpectBegin()
36
37 mock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE").
38 WithArgs(1).
39 WillReturnRows(NewRows(columns).AddRow(1, 1))
40
41 mock.ExpectRollback()
42
43
44 someOrderID := 1
45
46 err = cancelOrder(db, someOrderID)
47 if err != nil {
48 fmt.Printf("unexpected error: %s", err)
49 return
50 }
51
52
53 if err = mock.ExpectationsWereMet(); err != nil {
54 fmt.Printf("unmet expectation error: %s", err)
55 }
56
57 }
58
59 func TestIssue14EscapeSQL(t *testing.T) {
60 t.Parallel()
61 db, mock, err := New()
62 if err != nil {
63 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
64 }
65 defer db.Close()
66 mock.ExpectExec("INSERT INTO mytable\\(a, b\\)").
67 WithArgs("A", "B").
68 WillReturnResult(NewResult(1, 1))
69
70 _, err = db.Exec("INSERT INTO mytable(a, b) VALUES (?, ?)", "A", "B")
71 if err != nil {
72 t.Errorf("error '%s' was not expected, while inserting a row", err)
73 }
74
75 if err := mock.ExpectationsWereMet(); err != nil {
76 t.Errorf("there were unfulfilled expectations: %s", err)
77 }
78 }
79
80
81
82 func TestIssue4(t *testing.T) {
83 t.Parallel()
84 db, mock, err := New()
85 if err != nil {
86 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
87 }
88 defer db.Close()
89
90 mock.ExpectQuery("some sql query which will not be called").
91 WillReturnRows(NewRows([]string{"id"}))
92
93 if err := mock.ExpectationsWereMet(); err == nil {
94 t.Errorf("was expecting an error since query was not triggered")
95 }
96 }
97
98 func TestMockQuery(t *testing.T) {
99 t.Parallel()
100 db, mock, err := New()
101 if err != nil {
102 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
103 }
104 defer db.Close()
105
106 rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
107
108 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
109 WithArgs(5).
110 WillReturnRows(rs)
111
112 rows, err := db.Query("SELECT (.+) FROM articles WHERE id = ?", 5)
113 if err != nil {
114 t.Errorf("error '%s' was not expected while retrieving mock rows", err)
115 }
116
117 defer func() {
118 if er := rows.Close(); er != nil {
119 t.Error("unexpected error while trying to close rows")
120 }
121 }()
122
123 if !rows.Next() {
124 t.Error("it must have had one row as result, but got empty result set instead")
125 }
126
127 var id int
128 var title string
129
130 err = rows.Scan(&id, &title)
131 if err != nil {
132 t.Errorf("error '%s' was not expected while trying to scan row", err)
133 }
134
135 if id != 5 {
136 t.Errorf("expected mocked id to be 5, but got %d instead", id)
137 }
138
139 if title != "hello world" {
140 t.Errorf("expected mocked title to be 'hello world', but got '%s' instead", title)
141 }
142
143 if err := mock.ExpectationsWereMet(); err != nil {
144 t.Errorf("there were unfulfilled expectations: %s", err)
145 }
146 }
147
148 func TestMockQueryTypes(t *testing.T) {
149 t.Parallel()
150 db, mock, err := New()
151 if err != nil {
152 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
153 }
154 defer db.Close()
155
156 columns := []string{"id", "timestamp", "sold"}
157
158 timestamp := time.Now()
159 rs := NewRows(columns)
160 rs.AddRow(5, timestamp, true)
161
162 mock.ExpectQuery("SELECT (.+) FROM sales WHERE id = ?").
163 WithArgs(5).
164 WillReturnRows(rs)
165
166 rows, err := db.Query("SELECT (.+) FROM sales WHERE id = ?", 5)
167 if err != nil {
168 t.Errorf("error '%s' was not expected while retrieving mock rows", err)
169 }
170 defer func() {
171 if er := rows.Close(); er != nil {
172 t.Error("unexpected error while trying to close rows")
173 }
174 }()
175 if !rows.Next() {
176 t.Error("it must have had one row as result, but got empty result set instead")
177 }
178
179 var id int
180 var time time.Time
181 var sold bool
182
183 err = rows.Scan(&id, &time, &sold)
184 if err != nil {
185 t.Errorf("error '%s' was not expected while trying to scan row", err)
186 }
187
188 if id != 5 {
189 t.Errorf("expected mocked id to be 5, but got %d instead", id)
190 }
191
192 if time != timestamp {
193 t.Errorf("expected mocked time to be %s, but got '%s' instead", timestamp, time)
194 }
195
196 if sold != true {
197 t.Errorf("expected mocked boolean to be true, but got %v instead", sold)
198 }
199
200 if err := mock.ExpectationsWereMet(); err != nil {
201 t.Errorf("there were unfulfilled expectations: %s", err)
202 }
203 }
204
205 func TestTransactionExpectations(t *testing.T) {
206 t.Parallel()
207 db, mock, err := New()
208 if err != nil {
209 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
210 }
211 defer db.Close()
212
213
214 mock.ExpectBegin()
215 mock.ExpectCommit()
216
217 tx, err := db.Begin()
218 if err != nil {
219 t.Errorf("an error '%s' was not expected when beginning a transaction", err)
220 }
221
222 err = tx.Commit()
223 if err != nil {
224 t.Errorf("an error '%s' was not expected when committing a transaction", err)
225 }
226
227
228 mock.ExpectBegin()
229 mock.ExpectRollback()
230
231 tx, err = db.Begin()
232 if err != nil {
233 t.Errorf("an error '%s' was not expected when beginning a transaction", err)
234 }
235
236 err = tx.Rollback()
237 if err != nil {
238 t.Errorf("an error '%s' was not expected when rolling back a transaction", err)
239 }
240
241
242 mock.ExpectBegin().WillReturnError(fmt.Errorf("some err"))
243
244 tx, err = db.Begin()
245 if err == nil {
246 t.Error("an error was expected when beginning a transaction, but got none")
247 }
248
249 if err := mock.ExpectationsWereMet(); err != nil {
250 t.Errorf("there were unfulfilled expectations: %s", err)
251 }
252 }
253
254 func TestPrepareExpectations(t *testing.T) {
255 t.Parallel()
256 db, mock, err := New()
257 if err != nil {
258 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
259 }
260 defer db.Close()
261
262 mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?")
263
264 stmt, err := db.Prepare("SELECT (.+) FROM articles WHERE id = ?")
265 if err != nil {
266 t.Errorf("error '%s' was not expected while creating a prepared statement", err)
267 }
268 if stmt == nil {
269 t.Errorf("stmt was expected while creating a prepared statement")
270 }
271
272
273 var id int
274 var title string
275 rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
276
277 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
278 WithArgs(5).
279 WillReturnRows(rs)
280
281 err = stmt.QueryRow(5).Scan(&id, &title)
282 if err != nil {
283 t.Errorf("error '%s' was not expected while retrieving mock rows", err)
284 }
285
286 mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?").
287 WillReturnError(fmt.Errorf("Some DB error occurred"))
288
289 stmt, err = db.Prepare("SELECT id FROM articles WHERE id = ?")
290 if err == nil {
291 t.Error("error was expected while creating a prepared statement")
292 }
293 if stmt != nil {
294 t.Errorf("stmt was not expected while creating a prepared statement returning error")
295 }
296
297 if err := mock.ExpectationsWereMet(); err != nil {
298 t.Errorf("there were unfulfilled expectations: %s", err)
299 }
300 }
301
302 func TestPreparedQueryExecutions(t *testing.T) {
303 t.Parallel()
304 db, mock, err := New()
305 if err != nil {
306 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
307 }
308 defer db.Close()
309
310 mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?")
311
312 rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
313 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
314 WithArgs(5).
315 WillReturnRows(rs1)
316
317 rs2 := NewRows([]string{"id", "title"}).FromCSVString("2,whoop")
318 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
319 WithArgs(2).
320 WillReturnRows(rs2)
321
322 stmt, err := db.Prepare("SELECT id, title FROM articles WHERE id = ?")
323 if err != nil {
324 t.Errorf("error '%s' was not expected while creating a prepared statement", err)
325 }
326
327 var id int
328 var title string
329 err = stmt.QueryRow(5).Scan(&id, &title)
330 if err != nil {
331 t.Errorf("error '%s' was not expected querying row from statement and scanning", err)
332 }
333
334 if id != 5 {
335 t.Errorf("expected mocked id to be 5, but got %d instead", id)
336 }
337
338 if title != "hello world" {
339 t.Errorf("expected mocked title to be 'hello world', but got '%s' instead", title)
340 }
341
342 err = stmt.QueryRow(2).Scan(&id, &title)
343 if err != nil {
344 t.Errorf("error '%s' was not expected querying row from statement and scanning", err)
345 }
346
347 if id != 2 {
348 t.Errorf("expected mocked id to be 2, but got %d instead", id)
349 }
350
351 if title != "whoop" {
352 t.Errorf("expected mocked title to be 'whoop', but got '%s' instead", title)
353 }
354
355 if err := mock.ExpectationsWereMet(); err != nil {
356 t.Errorf("there were unfulfilled expectations: %s", err)
357 }
358 }
359
360 func TestUnorderedPreparedQueryExecutions(t *testing.T) {
361 t.Parallel()
362 db, mock, err := New()
363 if err != nil {
364 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
365 }
366 defer db.Close()
367
368 mock.MatchExpectationsInOrder(false)
369
370 mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?").
371 ExpectQuery().
372 WithArgs(5).
373 WillReturnRows(NewRows([]string{"id", "title"}).FromCSVString("5,The quick brown fox"))
374 mock.ExpectPrepare("SELECT (.+) FROM authors WHERE id = ?").
375 ExpectQuery().
376 WithArgs(1).
377 WillReturnRows(NewRows([]string{"id", "title"}).FromCSVString("1,Betty B."))
378
379 var id int
380 var name string
381
382 stmt, err := db.Prepare("SELECT id, name FROM authors WHERE id = ?")
383 if err != nil {
384 t.Errorf("error '%s' was not expected while creating a prepared statement", err)
385 }
386
387 err = stmt.QueryRow(1).Scan(&id, &name)
388 if err != nil {
389 t.Errorf("error '%s' was not expected querying row from statement and scanning", err)
390 }
391
392 if name != "Betty B." {
393 t.Errorf("expected mocked name to be 'Betty B.', but got '%s' instead", name)
394 }
395 }
396
397 func TestUnexpectedOperations(t *testing.T) {
398 t.Parallel()
399 db, mock, err := New()
400 if err != nil {
401 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
402 }
403 defer db.Close()
404
405 mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?")
406 stmt, err := db.Prepare("SELECT id, title FROM articles WHERE id = ?")
407 if err != nil {
408 t.Errorf("error '%s' was not expected while creating a prepared statement", err)
409 }
410
411 var id int
412 var title string
413
414 err = stmt.QueryRow(5).Scan(&id, &title)
415 if err == nil {
416 t.Error("error was expected querying row, since there was no such expectation")
417 }
418
419 mock.ExpectRollback()
420
421 if err := mock.ExpectationsWereMet(); err == nil {
422 t.Errorf("was expecting an error since query was not triggered")
423 }
424 }
425
426 func TestWrongExpectations(t *testing.T) {
427 t.Parallel()
428 db, mock, err := New()
429 if err != nil {
430 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
431 }
432 defer db.Close()
433
434 mock.ExpectBegin()
435
436 rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
437 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
438 WithArgs(5).
439 WillReturnRows(rs1)
440
441 mock.ExpectCommit().WillReturnError(fmt.Errorf("deadlock occurred"))
442 mock.ExpectRollback()
443
444 var id int
445 var title string
446
447 err = db.QueryRow("SELECT id, title FROM articles WHERE id = ? FOR UPDATE", 5).Scan(&id, &title)
448 if err == nil {
449 t.Error("error was expected while querying row, since there begin transaction expectation is not fulfilled")
450 }
451
452
453 tx, err := db.Begin()
454 if err != nil {
455 t.Errorf("an error '%s' was not expected when beginning a transaction", err)
456 }
457
458 err = db.QueryRow("SELECT id, title FROM articles WHERE id = ? FOR UPDATE", 5).Scan(&id, &title)
459 if err != nil {
460 t.Errorf("error '%s' was not expected while querying row, since transaction was started", err)
461 }
462
463 err = tx.Commit()
464 if err == nil {
465 t.Error("a deadlock error was expected when committing a transaction", err)
466 }
467
468 if err := mock.ExpectationsWereMet(); err == nil {
469 t.Errorf("was expecting an error since query was not triggered")
470 }
471 }
472
473 func TestExecExpectations(t *testing.T) {
474 t.Parallel()
475 db, mock, err := New()
476 if err != nil {
477 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
478 }
479 defer db.Close()
480
481 result := NewResult(1, 1)
482 mock.ExpectExec("^INSERT INTO articles").
483 WithArgs("hello").
484 WillReturnResult(result)
485
486 res, err := db.Exec("INSERT INTO articles (title) VALUES (?)", "hello")
487 if err != nil {
488 t.Errorf("error '%s' was not expected, while inserting a row", err)
489 }
490
491 id, err := res.LastInsertId()
492 if err != nil {
493 t.Errorf("error '%s' was not expected, while getting a last insert id", err)
494 }
495
496 affected, err := res.RowsAffected()
497 if err != nil {
498 t.Errorf("error '%s' was not expected, while getting affected rows", err)
499 }
500
501 if id != 1 {
502 t.Errorf("expected last insert id to be 1, but got %d instead", id)
503 }
504
505 if affected != 1 {
506 t.Errorf("expected affected rows to be 1, but got %d instead", affected)
507 }
508
509 if err := mock.ExpectationsWereMet(); err != nil {
510 t.Errorf("there were unfulfilled expectations: %s", err)
511 }
512 }
513
514 func TestRowBuilderAndNilTypes(t *testing.T) {
515 t.Parallel()
516 db, mock, err := New()
517 if err != nil {
518 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
519 }
520 defer db.Close()
521
522 rs := NewRows([]string{"id", "active", "created", "status"}).
523 AddRow(1, true, time.Now(), 5).
524 AddRow(2, false, nil, nil)
525
526 mock.ExpectQuery("SELECT (.+) FROM sales").WillReturnRows(rs)
527
528 rows, err := db.Query("SELECT * FROM sales")
529 if err != nil {
530 t.Errorf("error '%s' was not expected while retrieving mock rows", err)
531 }
532 defer func() {
533 if er := rows.Close(); er != nil {
534 t.Error("Unexpected error while trying to close rows")
535 }
536 }()
537
538
539 var (
540 id int
541 active bool
542 created NullTime
543 status NullInt
544 )
545
546 if !rows.Next() {
547 t.Error("it must have had row in rows, but got empty result set instead")
548 }
549
550 err = rows.Scan(&id, &active, &created, &status)
551 if err != nil {
552 t.Errorf("error '%s' was not expected while trying to scan row", err)
553 }
554
555 if id != 1 {
556 t.Errorf("expected mocked id to be 1, but got %d instead", id)
557 }
558
559 if !active {
560 t.Errorf("expected 'active' to be 'true', but got '%v' instead", active)
561 }
562
563 if !created.Valid {
564 t.Errorf("expected 'created' to be valid, but it %+v is not", created)
565 }
566
567 if !status.Valid {
568 t.Errorf("expected 'status' to be valid, but it %+v is not", status)
569 }
570
571 if status.Integer != 5 {
572 t.Errorf("expected 'status' to be '5', but got '%d'", status.Integer)
573 }
574
575
576 if !rows.Next() {
577 t.Error("it must have had row in rows, but got empty result set instead")
578 }
579
580 err = rows.Scan(&id, &active, &created, &status)
581 if err != nil {
582 t.Errorf("error '%s' was not expected while trying to scan row", err)
583 }
584
585 if id != 2 {
586 t.Errorf("expected mocked id to be 2, but got %d instead", id)
587 }
588
589 if active {
590 t.Errorf("expected 'active' to be 'false', but got '%v' instead", active)
591 }
592
593 if created.Valid {
594 t.Errorf("expected 'created' to be invalid, but it %+v is not", created)
595 }
596
597 if status.Valid {
598 t.Errorf("expected 'status' to be invalid, but it %+v is not", status)
599 }
600
601 if err := mock.ExpectationsWereMet(); err != nil {
602 t.Errorf("there were unfulfilled expectations: %s", err)
603 }
604 }
605
606 func TestArgumentReflectValueTypeError(t *testing.T) {
607 t.Parallel()
608 db, mock, err := New()
609 if err != nil {
610 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
611 }
612 defer db.Close()
613
614 rs := NewRows([]string{"id"}).AddRow(1)
615
616 mock.ExpectQuery("SELECT (.+) FROM sales").WithArgs(5.5).WillReturnRows(rs)
617
618 _, err = db.Query("SELECT * FROM sales WHERE x = ?", 5)
619 if err == nil {
620 t.Error("expected error, but got none")
621 }
622 }
623
624 func TestGoroutineExecutionWithUnorderedExpectationMatching(t *testing.T) {
625 t.Parallel()
626 db, mock, err := New()
627 if err != nil {
628 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
629 }
630 defer db.Close()
631
632
633 mock.MatchExpectationsInOrder(false)
634
635 result := NewResult(1, 1)
636
637 mock.ExpectExec("^UPDATE one").WithArgs("one").WillReturnResult(result)
638 mock.ExpectExec("^UPDATE two").WithArgs("one", "two").WillReturnResult(result)
639 mock.ExpectExec("^UPDATE three").WithArgs("one", "two", "three").WillReturnResult(result)
640
641 var wg sync.WaitGroup
642 queries := map[string][]interface{}{
643 "one": {"one"},
644 "two": {"one", "two"},
645 "three": {"one", "two", "three"},
646 }
647
648 wg.Add(len(queries))
649 for table, args := range queries {
650 go func(tbl string, a []interface{}) {
651 if _, err := db.Exec("UPDATE "+tbl, a...); err != nil {
652 t.Errorf("error was not expected: %s", err)
653 }
654 wg.Done()
655 }(table, args)
656 }
657
658 wg.Wait()
659
660 if err := mock.ExpectationsWereMet(); err != nil {
661 t.Errorf("there were unfulfilled expectations: %s", err)
662 }
663 }
664
665 func ExampleSqlmock_goroutines() {
666 db, mock, err := New()
667 if err != nil {
668 fmt.Println("failed to open sqlmock database:", err)
669 }
670 defer db.Close()
671
672
673 mock.MatchExpectationsInOrder(false)
674
675 result := NewResult(1, 1)
676
677 mock.ExpectExec("^UPDATE one").WithArgs("one").WillReturnResult(result)
678 mock.ExpectExec("^UPDATE two").WithArgs("one", "two").WillReturnResult(result)
679 mock.ExpectExec("^UPDATE three").WithArgs("one", "two", "three").WillReturnResult(result)
680
681 var wg sync.WaitGroup
682 queries := map[string][]interface{}{
683 "one": {"one"},
684 "two": {"one", "two"},
685 "three": {"one", "two", "three"},
686 }
687
688 wg.Add(len(queries))
689 for table, args := range queries {
690 go func(tbl string, a []interface{}) {
691 if _, err := db.Exec("UPDATE "+tbl, a...); err != nil {
692 fmt.Println("error was not expected:", err)
693 }
694 wg.Done()
695 }(table, args)
696 }
697
698 wg.Wait()
699
700 if err := mock.ExpectationsWereMet(); err != nil {
701 fmt.Println("there were unfulfilled expectations:", err)
702 }
703
704 }
705
706
707
708 func TestRunExecsWithOrderedShouldNotMeetAllExpectations(t *testing.T) {
709 db, dbmock, _ := New()
710 dbmock.ExpectExec("THE FIRST EXEC")
711 dbmock.ExpectExec("THE SECOND EXEC")
712
713 _, _ = db.Exec("THE FIRST EXEC")
714 _, _ = db.Exec("THE WRONG EXEC")
715
716 err := dbmock.ExpectationsWereMet()
717 if err == nil {
718 t.Fatal("was expecting an error, but there wasn't any")
719 }
720 }
721
722
723
724 func TestRunQueriesWithOrderedShouldNotMeetAllExpectations(t *testing.T) {
725 db, dbmock, _ := New()
726 dbmock.ExpectQuery("THE FIRST QUERY")
727 dbmock.ExpectQuery("THE SECOND QUERY")
728
729 _, _ = db.Query("THE FIRST QUERY")
730 _, _ = db.Query("THE WRONG QUERY")
731
732 err := dbmock.ExpectationsWereMet()
733 if err == nil {
734 t.Fatal("was expecting an error, but there wasn't any")
735 }
736 }
737
738 func TestRunExecsWithExpectedErrorMeetsExpectations(t *testing.T) {
739 db, dbmock, _ := New()
740 dbmock.ExpectExec("THE FIRST EXEC").WillReturnError(fmt.Errorf("big bad bug"))
741 dbmock.ExpectExec("THE SECOND EXEC").WillReturnResult(NewResult(0, 0))
742
743 _, _ = db.Exec("THE FIRST EXEC")
744 _, _ = db.Exec("THE SECOND EXEC")
745
746 err := dbmock.ExpectationsWereMet()
747 if err != nil {
748 t.Fatalf("all expectations should be met: %s", err)
749 }
750 }
751
752 func TestRunExecsWithNoArgsExpectedMeetsExpectations(t *testing.T) {
753 db, dbmock, _ := New()
754 dbmock.ExpectExec("THE FIRST EXEC").WithoutArgs().WillReturnResult(NewResult(0, 0))
755
756 _, err := db.Exec("THE FIRST EXEC", "foobar")
757 if err == nil {
758 t.Fatalf("expected error, but there wasn't any")
759 }
760 }
761
762 func TestRunQueryWithExpectedErrorMeetsExpectations(t *testing.T) {
763 db, dbmock, _ := New()
764 dbmock.ExpectQuery("THE FIRST QUERY").WillReturnError(fmt.Errorf("big bad bug"))
765 dbmock.ExpectQuery("THE SECOND QUERY").WillReturnRows(NewRows([]string{"col"}).AddRow(1))
766
767 _, _ = db.Query("THE FIRST QUERY")
768 _, _ = db.Query("THE SECOND QUERY")
769
770 err := dbmock.ExpectationsWereMet()
771 if err != nil {
772 t.Fatalf("all expectations should be met: %s", err)
773 }
774 }
775
776 func TestEmptyRowSet(t *testing.T) {
777 t.Parallel()
778 db, mock, err := New()
779 if err != nil {
780 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
781 }
782 defer db.Close()
783
784 rs := NewRows([]string{"id", "title"})
785
786 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
787 WithArgs(5).
788 WillReturnRows(rs)
789
790 rows, err := db.Query("SELECT (.+) FROM articles WHERE id = ?", 5)
791 if err != nil {
792 t.Errorf("error '%s' was not expected while retrieving mock rows", err)
793 }
794
795 defer func() {
796 if er := rows.Close(); er != nil {
797 t.Error("unexpected error while trying to close rows")
798 }
799 }()
800
801 if rows.Next() {
802 t.Error("expected no rows but got one")
803 }
804
805 err = mock.ExpectationsWereMet()
806 if err != nil {
807 t.Fatalf("all expectations should be met: %s", err)
808 }
809 }
810
811
812 func TestPrepareExpectationNotFulfilled(t *testing.T) {
813 t.Parallel()
814 db, mock, err := New()
815 if err != nil {
816 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
817 }
818 defer db.Close()
819
820 mock.ExpectPrepare("^BADSELECT$")
821
822 if _, err := db.Prepare("SELECT"); err == nil {
823 t.Fatal("prepare should not match expected query string")
824 }
825
826 if err := mock.ExpectationsWereMet(); err == nil {
827 t.Errorf("was expecting an error, since prepared statement query does not match, but there was none")
828 }
829 }
830
831 func TestRollbackThrow(t *testing.T) {
832
833 db, mock, err := New()
834 if err != nil {
835 fmt.Println("error creating mock database")
836 return
837 }
838
839 columns := []string{"id", "status"}
840
841 mock.ExpectBegin()
842
843 mock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE").
844 WithArgs(1).
845 WillReturnRows(NewRows(columns).AddRow(1, 1))
846
847 mock.ExpectRollback().WillReturnError(fmt.Errorf("rollback failed"))
848
849
850 someOrderID := 1
851
852 err = cancelOrder(db, someOrderID)
853 if err == nil {
854 t.Error("an error was expected when rolling back transaction, but got none")
855 }
856
857
858 if err = mock.ExpectationsWereMet(); err != nil {
859 t.Errorf("unmet expectation error: %s", err)
860 }
861
862 }
863
864 func TestUnexpectedBegin(t *testing.T) {
865
866 db, _, err := New()
867 if err != nil {
868 fmt.Println("error creating mock database")
869 return
870 }
871 if _, err := db.Begin(); err == nil {
872 t.Error("an error was expected when calling begin, but got none")
873 }
874 }
875
876 func TestUnexpectedExec(t *testing.T) {
877
878 db, mock, err := New()
879 if err != nil {
880 fmt.Println("error creating mock database")
881 return
882 }
883 mock.ExpectBegin()
884 db.Begin()
885 if _, err := db.Exec("SELECT 1"); err == nil {
886 t.Error("an error was expected when calling exec, but got none")
887 }
888 }
889
890 func TestUnexpectedCommit(t *testing.T) {
891
892 db, mock, err := New()
893 if err != nil {
894 fmt.Println("error creating mock database")
895 return
896 }
897 mock.ExpectBegin()
898 tx, _ := db.Begin()
899 if err := tx.Commit(); err == nil {
900 t.Error("an error was expected when calling commit, but got none")
901 }
902 }
903
904 func TestUnexpectedCommitOrder(t *testing.T) {
905
906 db, mock, err := New()
907 if err != nil {
908 fmt.Println("error creating mock database")
909 return
910 }
911 mock.ExpectBegin()
912 mock.ExpectRollback().WillReturnError(fmt.Errorf("Rollback failed"))
913 tx, _ := db.Begin()
914 if err := tx.Commit(); err == nil {
915 t.Error("an error was expected when calling commit, but got none")
916 }
917 }
918
919 func TestExpectedCommitOrder(t *testing.T) {
920
921 db, mock, err := New()
922 if err != nil {
923 fmt.Println("error creating mock database")
924 return
925 }
926 mock.ExpectCommit().WillReturnError(fmt.Errorf("Commit failed"))
927 if _, err := db.Begin(); err == nil {
928 t.Error("an error was expected when calling begin, but got none")
929 }
930 }
931
932 func TestUnexpectedRollback(t *testing.T) {
933
934 db, mock, err := New()
935 if err != nil {
936 fmt.Println("error creating mock database")
937 return
938 }
939 mock.ExpectBegin()
940 tx, _ := db.Begin()
941 if err := tx.Rollback(); err == nil {
942 t.Error("an error was expected when calling rollback, but got none")
943 }
944 }
945
946 func TestUnexpectedRollbackOrder(t *testing.T) {
947
948 db, mock, err := New()
949 if err != nil {
950 fmt.Println("error creating mock database")
951 return
952 }
953 mock.ExpectBegin()
954
955 tx, _ := db.Begin()
956 if err := tx.Rollback(); err == nil {
957 t.Error("an error was expected when calling rollback, but got none")
958 }
959 }
960
961 func TestPrepareExec(t *testing.T) {
962
963 db, mock, err := New()
964 if err != nil {
965 fmt.Println("error creating mock database")
966 return
967 }
968 defer db.Close()
969 mock.ExpectBegin()
970 ep := mock.ExpectPrepare("INSERT INTO ORDERS\\(ID, STATUS\\) VALUES \\(\\?, \\?\\)")
971 for i := 0; i < 3; i++ {
972 ep.ExpectExec().WillReturnResult(NewResult(1, 1))
973 }
974 mock.ExpectCommit()
975 tx, _ := db.Begin()
976 stmt, err := tx.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)")
977 if err != nil {
978 t.Fatal(err)
979 }
980 defer stmt.Close()
981 for i := 0; i < 3; i++ {
982 _, err := stmt.Exec(i, "Hello"+strconv.Itoa(i))
983 if err != nil {
984 t.Fatal(err)
985 }
986 }
987 tx.Commit()
988 if err := mock.ExpectationsWereMet(); err != nil {
989 t.Errorf("there were unfulfilled expectations: %s", err)
990 }
991 }
992
993 func TestPrepareQuery(t *testing.T) {
994
995 db, mock, err := New()
996 if err != nil {
997 fmt.Println("error creating mock database")
998 return
999 }
1000 defer db.Close()
1001 mock.ExpectBegin()
1002 ep := mock.ExpectPrepare("SELECT ID, STATUS FROM ORDERS WHERE ID = \\?")
1003 ep.ExpectQuery().WithArgs(101).WillReturnRows(NewRows([]string{"ID", "STATUS"}).AddRow(101, "Hello"))
1004 mock.ExpectCommit()
1005 tx, _ := db.Begin()
1006 stmt, err := tx.Prepare("SELECT ID, STATUS FROM ORDERS WHERE ID = ?")
1007 if err != nil {
1008 t.Fatal(err)
1009 }
1010 defer stmt.Close()
1011 rows, err := stmt.Query(101)
1012 if err != nil {
1013 t.Fatal(err)
1014 }
1015 defer rows.Close()
1016 for rows.Next() {
1017 var (
1018 id int
1019 status string
1020 )
1021 if rows.Scan(&id, &status); id != 101 || status != "Hello" {
1022 t.Fatal("wrong query results")
1023 }
1024
1025 }
1026 tx.Commit()
1027 if err := mock.ExpectationsWereMet(); err != nil {
1028 t.Errorf("there were unfulfilled expectations: %s", err)
1029 }
1030 }
1031
1032 func TestExpectedCloseError(t *testing.T) {
1033
1034 db, mock, err := New()
1035 if err != nil {
1036 fmt.Println("error creating mock database")
1037 return
1038 }
1039 mock.ExpectClose().WillReturnError(fmt.Errorf("Close failed"))
1040 if err := db.Close(); err == nil {
1041 t.Error("an error was expected when calling close, but got none")
1042 }
1043 if err := mock.ExpectationsWereMet(); err != nil {
1044 t.Errorf("there were unfulfilled expectations: %s", err)
1045 }
1046 }
1047
1048 func TestExpectedCloseOrder(t *testing.T) {
1049
1050 db, mock, err := New()
1051 if err != nil {
1052 fmt.Println("error creating mock database")
1053 return
1054 }
1055 defer db.Close()
1056 mock.ExpectClose().WillReturnError(fmt.Errorf("Close failed"))
1057 db.Begin()
1058 if err := mock.ExpectationsWereMet(); err == nil {
1059 t.Error("expected error on ExpectationsWereMet")
1060 }
1061 }
1062
1063 func TestExpectedBeginOrder(t *testing.T) {
1064
1065 db, mock, err := New()
1066 if err != nil {
1067 fmt.Println("error creating mock database")
1068 return
1069 }
1070 mock.ExpectBegin().WillReturnError(fmt.Errorf("Begin failed"))
1071 if err := db.Close(); err == nil {
1072 t.Error("an error was expected when calling close, but got none")
1073 }
1074 }
1075
1076 func TestPreparedStatementCloseExpectation(t *testing.T) {
1077
1078 db, mock, err := New()
1079 if err != nil {
1080 fmt.Println("error creating mock database")
1081 return
1082 }
1083 defer db.Close()
1084
1085 ep := mock.ExpectPrepare("INSERT INTO ORDERS").WillBeClosed()
1086 ep.ExpectExec().WillReturnResult(NewResult(1, 1))
1087
1088 stmt, err := db.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)")
1089 if err != nil {
1090 t.Fatal(err)
1091 }
1092
1093 if _, err := stmt.Exec(1, "Hello"); err != nil {
1094 t.Fatal(err)
1095 }
1096
1097 if err := stmt.Close(); err != nil {
1098 t.Fatal(err)
1099 }
1100
1101 if err := mock.ExpectationsWereMet(); err != nil {
1102 t.Errorf("there were unfulfilled expectations: %s", err)
1103 }
1104 }
1105
1106 func TestExecExpectationErrorDelay(t *testing.T) {
1107 t.Parallel()
1108 db, mock, err := New()
1109 if err != nil {
1110 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1111 }
1112 defer db.Close()
1113
1114
1115 var delay time.Duration = 100 * time.Millisecond
1116 mock.ExpectExec("^INSERT INTO articles").
1117 WillReturnError(errors.New("slow fail")).
1118 WillDelayFor(delay)
1119
1120 start := time.Now()
1121 res, err := db.Exec("INSERT INTO articles (title) VALUES (?)", "hello")
1122 stop := time.Now()
1123
1124 if res != nil {
1125 t.Errorf("result was not expected, was expecting nil")
1126 }
1127
1128 if err == nil {
1129 t.Errorf("error was expected, was not expecting nil")
1130 }
1131
1132 if err.Error() != "slow fail" {
1133 t.Errorf("error '%s' was not expected, was expecting '%s'", err.Error(), "slow fail")
1134 }
1135
1136 elapsed := stop.Sub(start)
1137 if elapsed < delay {
1138 t.Errorf("expecting a delay of %v before error, actual delay was %v", delay, elapsed)
1139 }
1140
1141
1142 mock.ExpectExec("^INSERT INTO articles").WillReturnError(errors.New("fast fail"))
1143
1144 start = time.Now()
1145 db.Exec("INSERT INTO articles (title) VALUES (?)", "hello")
1146 stop = time.Now()
1147
1148 elapsed = stop.Sub(start)
1149 if elapsed > delay {
1150 t.Errorf("expecting a delay of less than %v before error, actual delay was %v", delay, elapsed)
1151 }
1152 }
1153
1154 func TestOptionsFail(t *testing.T) {
1155 t.Parallel()
1156 expected := errors.New("failing option")
1157 option := func(*sqlmock) error {
1158 return expected
1159 }
1160 db, _, err := New(option)
1161 defer db.Close()
1162 if err == nil {
1163 t.Errorf("missing expecting error '%s' when opening a stub database connection", expected)
1164 }
1165 }
1166
1167 func TestNewRows(t *testing.T) {
1168 t.Parallel()
1169 db, mock, err := New()
1170 if err != nil {
1171 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1172 }
1173 defer db.Close()
1174 columns := []string{"col1", "col2"}
1175
1176 r := mock.NewRows(columns)
1177 if len(r.cols) != len(columns) || r.cols[0] != columns[0] || r.cols[1] != columns[1] {
1178 t.Errorf("expecting to create a row with columns %v, actual colmns are %v", r.cols, columns)
1179 }
1180 }
1181
1182
1183
1184
1185 func TestQueryWithTimeout(t *testing.T) {
1186 db, mock, err := New()
1187 if err != nil {
1188 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1189 }
1190 defer db.Close()
1191
1192 rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
1193
1194 mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
1195 WillDelayFor(15 * time.Millisecond).
1196 WithArgs(5).
1197 WillReturnRows(rs)
1198
1199 _, err = queryWithTimeout(10*time.Millisecond, db, "SELECT (.+) FROM articles WHERE id = ?", 5)
1200 if err == nil {
1201 t.Errorf("expecting query to time out")
1202 }
1203
1204 if err := mock.ExpectationsWereMet(); err != nil {
1205 t.Errorf("there were unfulfilled expectations: %s", err)
1206 }
1207 }
1208
1209 func queryWithTimeout(t time.Duration, db *sql.DB, query string, args ...interface{}) (*sql.Rows, error) {
1210 rowsChan := make(chan *sql.Rows, 1)
1211 errChan := make(chan error, 1)
1212
1213 go func() {
1214 rows, err := db.Query(query, args...)
1215 if err != nil {
1216 errChan <- err
1217 return
1218 }
1219 rowsChan <- rows
1220 }()
1221
1222 select {
1223 case rows := <-rowsChan:
1224 return rows, nil
1225 case err := <-errChan:
1226 return nil, err
1227 case <-time.After(t):
1228 return nil, fmt.Errorf("query timed out after %v", t)
1229 }
1230 }
1231
1232 func Test_sqlmock_Prepare_and_Exec(t *testing.T) {
1233 db, mock, err := New()
1234 if err != nil {
1235 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1236 }
1237 defer db.Close()
1238 query := "SELECT name, email FROM users WHERE name = ?"
1239
1240 mock.ExpectPrepare("SELECT (.+) FROM users WHERE (.+)")
1241 expected := NewResult(1, 1)
1242 mock.ExpectExec("SELECT (.+) FROM users WHERE (.+)").
1243 WillReturnResult(expected)
1244 expectedRows := mock.NewRows([]string{"id", "name", "email"}).AddRow(1, "test", "test@example.com")
1245 mock.ExpectQuery("SELECT (.+) FROM users WHERE (.+)").WillReturnRows(expectedRows)
1246
1247 got, err := mock.(*sqlmock).Prepare(query)
1248 if err != nil {
1249 t.Error(err)
1250 return
1251 }
1252 if got == nil {
1253 t.Error("Prepare () stmt must not be nil")
1254 return
1255 }
1256 result, err := got.Exec([]driver.Value{"test"})
1257 if err != nil {
1258 t.Error(err)
1259 return
1260 }
1261 if !reflect.DeepEqual(result, expected) {
1262 t.Errorf("Results are not equal. Expected: %v, Actual: %v", expected, result)
1263 return
1264 }
1265 rows, err := got.Query([]driver.Value{"test"})
1266 if err != nil {
1267 t.Error(err)
1268 return
1269 }
1270 defer rows.Close()
1271 }
1272
1273 type failArgument struct{}
1274
1275 func (f failArgument) Match(_ driver.Value) bool {
1276 return false
1277 }
1278
1279 func Test_sqlmock_Exec(t *testing.T) {
1280 db, mock, err := New()
1281 if err != nil {
1282 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1283 }
1284 defer db.Close()
1285
1286 mock.ExpectBegin()
1287 _, err = mock.(*sqlmock).Exec("", []driver.Value{})
1288 if err == nil {
1289 t.Errorf("error expected")
1290 return
1291 }
1292
1293 expected := NewResult(1, 1)
1294 mock.ExpectExec("SELECT (.+) FROM users WHERE (.+)").
1295 WillReturnResult(expected).
1296 WithArgs("test")
1297
1298 matchErr := errors.New("matcher sqlmock.failArgument could not match 0 argument driver.NamedValue - {Name: Ordinal:1 Value:{}}")
1299 mock.ExpectExec("SELECT (.+) FROM animals WHERE (.+)").
1300 WillReturnError(matchErr).
1301 WithArgs(failArgument{})
1302
1303 mock.ExpectExec("").WithArgs(failArgument{})
1304
1305 mock.(*sqlmock).expected = mock.(*sqlmock).expected[1:]
1306 query := "SELECT name, email FROM users WHERE name = ?"
1307 result, err := mock.(*sqlmock).Exec(query, []driver.Value{"test"})
1308 if err != nil {
1309 t.Error(err)
1310 return
1311 }
1312 if !reflect.DeepEqual(result, expected) {
1313 t.Errorf("Results are not equal. Expected: %v, Actual: %v", expected, result)
1314 return
1315 }
1316
1317 failQuery := "SELECT name, sex FROM animals WHERE sex = ?"
1318 _, err = mock.(*sqlmock).Exec(failQuery, []driver.Value{failArgument{}})
1319 if err == nil {
1320 t.Errorf("error expected")
1321 return
1322 }
1323 mock.(*sqlmock).ordered = false
1324 _, err = mock.(*sqlmock).Exec("", []driver.Value{failArgument{}})
1325 if err == nil {
1326 t.Errorf("error expected")
1327 return
1328 }
1329 }
1330
1331 func Test_sqlmock_Query(t *testing.T) {
1332 db, mock, err := New()
1333 if err != nil {
1334 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1335 }
1336 defer db.Close()
1337 expectedRows := mock.NewRows([]string{"id", "name", "email"}).AddRow(1, "test", "test@example.com")
1338 mock.ExpectQuery("SELECT (.+) FROM users WHERE (.+)").WillReturnRows(expectedRows)
1339 query := "SELECT name, email FROM users WHERE name = ?"
1340 rows, err := mock.(*sqlmock).Query(query, []driver.Value{"test"})
1341 if err != nil {
1342 t.Error(err)
1343 return
1344 }
1345 defer rows.Close()
1346 _, err = mock.(*sqlmock).Query(query, []driver.Value{failArgument{}})
1347 if err == nil {
1348 t.Errorf("error expected")
1349 return
1350 }
1351 }
1352
1353 func Test_sqlmock_QueryExpectWithoutArgs(t *testing.T) {
1354 db, mock, err := New()
1355 if err != nil {
1356 t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
1357 }
1358 defer db.Close()
1359 expectedRows := mock.NewRows([]string{"id", "name", "email"}).AddRow(1, "test", "test@example.com")
1360 mock.ExpectQuery("SELECT (.+) FROM users WHERE (.+)").WillReturnRows(expectedRows).WithoutArgs()
1361 query := "SELECT name, email FROM users WHERE name = ?"
1362 _, err = mock.(*sqlmock).Query(query, []driver.Value{"test"})
1363 if err == nil {
1364 t.Errorf("error expected")
1365 return
1366 }
1367 }
1368
View as plain text