| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | package sqlmock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"database/sql" | 
					
						
							| 
									
										
										
										
											2018-02-20 17:30:20 -07:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2015-08-26 14:28:01 +03:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | func cancelOrder(db *sql.DB, orderID int) error { | 
					
						
							|  |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	_, _ = tx.Query("SELECT * FROM orders {0} FOR UPDATE", orderID) | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 	err := tx.Rollback() | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Example() { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// columns to be used for result | 
					
						
							|  |  |  | 	columns := []string{"id", "status"} | 
					
						
							|  |  |  | 	// expect transaction begin | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	// expect query to fetch order, match it with regexp | 
					
						
							|  |  |  | 	mock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE"). | 
					
						
							|  |  |  | 		WithArgs(1). | 
					
						
							|  |  |  | 		WillReturnRows(NewRows(columns).AddRow(1, 1)) | 
					
						
							|  |  |  | 	// expect transaction rollback, since order status is "cancelled" | 
					
						
							|  |  |  | 	mock.ExpectRollback() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// run the cancel order function | 
					
						
							|  |  |  | 	someOrderID := 1 | 
					
						
							|  |  |  | 	// call a function which executes expected database operations | 
					
						
							|  |  |  | 	err = cancelOrder(db, someOrderID) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Printf("unexpected error: %s", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ensure all expectations have been met | 
					
						
							|  |  |  | 	if err = mock.ExpectationsWereMet(); err != nil { | 
					
						
							|  |  |  | 		fmt.Printf("unmet expectation error: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Output: | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-30 21:38:39 +03:00
										 |  |  | func TestIssue14EscapeSQL(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2015-03-30 21:38:39 +03:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 	mock.ExpectExec("INSERT INTO mytable\\(a, b\\)"). | 
					
						
							| 
									
										
										
										
											2015-03-30 21:38:39 +03:00
										 |  |  | 		WithArgs("A", "B"). | 
					
						
							|  |  |  | 		WillReturnResult(NewResult(1, 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = db.Exec("INSERT INTO mytable(a, b) VALUES (?, ?)", "A", "B") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected, while inserting a row", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2015-03-30 21:38:39 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-21 18:21:28 +03:00
										 |  |  | // test the case when db is not triggered and expectations | 
					
						
							|  |  |  | // are not asserted on close | 
					
						
							|  |  |  | func TestIssue4(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-04-21 18:21:28 +03:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectQuery("some sql query which will not be called"). | 
					
						
							| 
									
										
										
										
											2014-04-21 18:21:28 +03:00
										 |  |  | 		WillReturnRows(NewRows([]string{"id"})) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err == nil { | 
					
						
							|  |  |  | 		t.Errorf("was expecting an error since query was not triggered") | 
					
						
							| 
									
										
										
										
											2014-04-21 18:21:28 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | func TestMockQuery(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 00:14:32 +02:00
										 |  |  | 	rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rows, err := db.Query("SELECT (.+) FROM articles WHERE id = ?", 5) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected while retrieving mock rows", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-30 22:32:57 +03:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if er := rows.Close(); er != nil { | 
					
						
							|  |  |  | 			t.Error("Unexpected error while trying to close rows") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if !rows.Next() { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Error("it must have had one row as result, but got empty result set instead") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var title string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = rows.Scan(&id, &title) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected while trying to scan row", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 5 { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked id to be 5, but got %d instead", id) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if title != "hello world" { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked title to be 'hello world', but got '%s' instead", title) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | func TestMockQueryTypes(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	columns := []string{"id", "timestamp", "sold"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	timestamp := time.Now() | 
					
						
							|  |  |  | 	rs := NewRows(columns) | 
					
						
							|  |  |  | 	rs.AddRow(5, timestamp, true) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM sales WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rows, err := db.Query("SELECT (.+) FROM sales WHERE id = ?", 5) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while retrieving mock rows", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-30 22:32:57 +03:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if er := rows.Close(); er != nil { | 
					
						
							|  |  |  | 			t.Error("Unexpected error while trying to close rows") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 	if !rows.Next() { | 
					
						
							|  |  |  | 		t.Error("it must have had one row as result, but got empty result set instead") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var time time.Time | 
					
						
							|  |  |  | 	var sold bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = rows.Scan(&id, &time, &sold) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while trying to scan row", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 5 { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked id to be 5, but got %d instead", id) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if time != timestamp { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked time to be %s, but got '%s' instead", timestamp, time) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if sold != true { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked boolean to be true, but got %v instead", sold) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-13 11:59:35 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | func TestTransactionExpectations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// begin and commit | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	mock.ExpectCommit() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tx, err := db.Begin() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when beginning a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = tx.Commit() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when committing a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// begin and rollback | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	mock.ExpectRollback() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tx, err = db.Begin() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when beginning a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = tx.Rollback() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when rolling back a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// begin with an error | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectBegin().WillReturnError(fmt.Errorf("some err")) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tx, err = db.Begin() | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Error("an error was expected when beginning a transaction, but got none") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | func TestPrepareExpectations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?") | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	stmt, err := db.Prepare("SELECT (.+) FROM articles WHERE id = ?") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while creating a prepared statement", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if stmt == nil { | 
					
						
							|  |  |  | 		t.Errorf("stmt was expected while creating a prepared statement") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// expect something else, w/o ExpectPrepare() | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var title string | 
					
						
							|  |  |  | 	rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = stmt.QueryRow(5).Scan(&id, &title) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while retrieving mock rows", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							|  |  |  | 		WillReturnError(fmt.Errorf("Some DB error occurred")) | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	stmt, err = db.Prepare("SELECT id FROM articles WHERE id = ?") | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Error("error was expected while creating a prepared statement") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if stmt != nil { | 
					
						
							|  |  |  | 		t.Errorf("stmt was not expected while creating a prepared statement returning error") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-09-24 16:05:15 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | func TestPreparedQueryExecutions(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 00:14:32 +02:00
										 |  |  | 	rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world") | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 00:14:32 +02:00
										 |  |  | 	rs2 := NewRows([]string{"id", "title"}).FromCSVString("2,whoop") | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 		WithArgs(2). | 
					
						
							|  |  |  | 		WillReturnRows(rs2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	stmt, err := db.Prepare("SELECT id, title FROM articles WHERE id = ?") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected while creating a prepared statement", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var title string | 
					
						
							|  |  |  | 	err = stmt.QueryRow(5).Scan(&id, &title) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected querying row from statement and scanning", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 5 { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked id to be 5, but got %d instead", id) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if title != "hello world" { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked title to be 'hello world', but got '%s' instead", title) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = stmt.QueryRow(2).Scan(&id, &title) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected querying row from statement and scanning", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 2 { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked id to be 2, but got %d instead", id) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if title != "whoop" { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected mocked title to be 'whoop', but got '%s' instead", title) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-30 15:44:56 -04:00
										 |  |  | func TestUnorderedPreparedQueryExecutions(t *testing.T) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.MatchExpectationsInOrder(false) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							|  |  |  | 		ExpectQuery(). | 
					
						
							|  |  |  | 		WithArgs(5). | 
					
						
							| 
									
										
										
										
											2017-06-02 11:59:07 +03:00
										 |  |  | 		WillReturnRows(NewRows([]string{"id", "title"}).FromCSVString("5,The quick brown fox")) | 
					
						
							| 
									
										
										
										
											2017-05-30 15:44:56 -04:00
										 |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM authors WHERE id = ?"). | 
					
						
							|  |  |  | 		ExpectQuery(). | 
					
						
							|  |  |  | 		WithArgs(1). | 
					
						
							| 
									
										
										
										
											2017-06-02 11:59:07 +03:00
										 |  |  | 		WillReturnRows(NewRows([]string{"id", "title"}).FromCSVString("1,Betty B.")) | 
					
						
							| 
									
										
										
										
											2017-05-30 15:44:56 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var name string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stmt, err := db.Prepare("SELECT id, name FROM authors WHERE id = ?") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while creating a prepared statement", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = stmt.QueryRow(1).Scan(&id, &name) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected querying row from statement and scanning", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if name != "Betty B." { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked name to be 'Betty B.', but got '%s' instead", name) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | func TestUnexpectedOperations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectPrepare("SELECT (.+) FROM articles WHERE id = ?") | 
					
						
							|  |  |  | 	stmt, err := db.Prepare("SELECT id, title FROM articles WHERE id = ?") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected while creating a prepared statement", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var title string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = stmt.QueryRow(5).Scan(&id, &title) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Error("error was expected querying row, since there was no such expectation") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectRollback() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err == nil { | 
					
						
							|  |  |  | 		t.Errorf("was expecting an error since query was not triggered") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 16:52:26 +02:00
										 |  |  | func TestWrongExpectations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectBegin() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 00:14:32 +02:00
										 |  |  | 	rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world") | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 	mock.ExpectCommit().WillReturnError(fmt.Errorf("deadlock occurred")) | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectRollback() // won't be triggered | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var id int | 
					
						
							|  |  |  | 	var title string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	err = db.QueryRow("SELECT id, title FROM articles WHERE id = ? FOR UPDATE", 5).Scan(&id, &title) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Error("error was expected while querying row, since there begin transaction expectation is not fulfilled") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// lets go around and start transaction | 
					
						
							|  |  |  | 	tx, err := db.Begin() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when beginning a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	err = db.QueryRow("SELECT id, title FROM articles WHERE id = ? FOR UPDATE", 5).Scan(&id, &title) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected while querying row, since transaction was started", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = tx.Commit() | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 		t.Error("a deadlock error was expected when committing a transaction", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err == nil { | 
					
						
							|  |  |  | 		t.Errorf("was expecting an error since query was not triggered") | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestExecExpectations(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	result := NewResult(1, 1) | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectExec("^INSERT INTO articles"). | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 		WithArgs("hello"). | 
					
						
							|  |  |  | 		WillReturnResult(result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res, err := db.Exec("INSERT INTO articles (title) VALUES (?)", "hello") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected, while inserting a row", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	id, err := res.LastInsertId() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected, while getting a last insert id", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	affected, err := res.RowsAffected() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("error '%s' was not expected, while getting affected rows", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 1 { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected last insert id to be 1, but got %d instead", id) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if affected != 1 { | 
					
						
							| 
									
										
										
										
											2014-02-08 17:51:58 +02:00
										 |  |  | 		t.Errorf("expected affected rows to be 1, but got %d instead", affected) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-05 16:21:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRowBuilderAndNilTypes(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rs := NewRows([]string{"id", "active", "created", "status"}). | 
					
						
							|  |  |  | 		AddRow(1, true, time.Now(), 5). | 
					
						
							|  |  |  | 		AddRow(2, false, nil, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM sales").WillReturnRows(rs) | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rows, err := db.Query("SELECT * FROM sales") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while retrieving mock rows", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-30 22:32:57 +03:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if er := rows.Close(); er != nil { | 
					
						
							|  |  |  | 			t.Error("Unexpected error while trying to close rows") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// NullTime and NullInt are used from stubs_test.go | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		id      int | 
					
						
							|  |  |  | 		active  bool | 
					
						
							|  |  |  | 		created NullTime | 
					
						
							|  |  |  | 		status  NullInt | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !rows.Next() { | 
					
						
							|  |  |  | 		t.Error("it must have had row in rows, but got empty result set instead") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = rows.Scan(&id, &active, &created, &status) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while trying to scan row", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 1 { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked id to be 1, but got %d instead", id) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !active { | 
					
						
							|  |  |  | 		t.Errorf("expected 'active' to be 'true', but got '%v' instead", active) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !created.Valid { | 
					
						
							|  |  |  | 		t.Errorf("expected 'created' to be valid, but it %+v is not", created) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !status.Valid { | 
					
						
							|  |  |  | 		t.Errorf("expected 'status' to be valid, but it %+v is not", status) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if status.Integer != 5 { | 
					
						
							|  |  |  | 		t.Errorf("expected 'status' to be '5', but got '%d'", status.Integer) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test second row | 
					
						
							|  |  |  | 	if !rows.Next() { | 
					
						
							|  |  |  | 		t.Error("it must have had row in rows, but got empty result set instead") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = rows.Scan(&id, &active, &created, &status) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while trying to scan row", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if id != 2 { | 
					
						
							|  |  |  | 		t.Errorf("expected mocked id to be 2, but got %d instead", id) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if active { | 
					
						
							|  |  |  | 		t.Errorf("expected 'active' to be 'false', but got '%v' instead", active) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if created.Valid { | 
					
						
							|  |  |  | 		t.Errorf("expected 'created' to be invalid, but it %+v is not", created) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if status.Valid { | 
					
						
							|  |  |  | 		t.Errorf("expected 'status' to be invalid, but it %+v is not", status) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2014-02-14 17:15:06 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-16 12:48:11 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestArgumentReflectValueTypeError(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							| 
									
										
										
										
											2014-08-16 12:48:11 +03:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	defer db.Close() | 
					
						
							| 
									
										
										
										
											2014-08-16 12:48:11 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rs := NewRows([]string{"id"}).AddRow(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-17 13:14:30 +03:00
										 |  |  | 	mock.ExpectQuery("SELECT (.+) FROM sales").WithArgs(5.5).WillReturnRows(rs) | 
					
						
							| 
									
										
										
										
											2014-08-16 12:48:11 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	_, err = db.Query("SELECT * FROM sales WHERE x = ?", 5) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Error("Expected error, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-08-26 14:28:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestGoroutineExecutionWithUnorderedExpectationMatching(t *testing.T) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// note this line is important for unordered expectation matching | 
					
						
							| 
									
										
										
										
											2015-08-28 11:06:14 +03:00
										 |  |  | 	mock.MatchExpectationsInOrder(false) | 
					
						
							| 
									
										
										
										
											2015-08-26 14:28:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	result := NewResult(1, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE one").WithArgs("one").WillReturnResult(result) | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE two").WithArgs("one", "two").WillReturnResult(result) | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE three").WithArgs("one", "two", "three").WillReturnResult(result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var wg sync.WaitGroup | 
					
						
							|  |  |  | 	queries := map[string][]interface{}{ | 
					
						
							|  |  |  | 		"one":   []interface{}{"one"}, | 
					
						
							|  |  |  | 		"two":   []interface{}{"one", "two"}, | 
					
						
							|  |  |  | 		"three": []interface{}{"one", "two", "three"}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Add(len(queries)) | 
					
						
							|  |  |  | 	for table, args := range queries { | 
					
						
							|  |  |  | 		go func(tbl string, a []interface{}) { | 
					
						
							|  |  |  | 			if _, err := db.Exec("UPDATE "+tbl, a...); err != nil { | 
					
						
							|  |  |  | 				t.Errorf("error was not expected: %s", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			wg.Done() | 
					
						
							|  |  |  | 		}(table, args) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2015-08-26 14:28:01 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-08-27 10:34:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func ExampleSqlmock_goroutines() { | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("failed to open sqlmock database:", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// note this line is important for unordered expectation matching | 
					
						
							| 
									
										
										
										
											2015-08-28 11:06:14 +03:00
										 |  |  | 	mock.MatchExpectationsInOrder(false) | 
					
						
							| 
									
										
										
										
											2015-08-27 10:34:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	result := NewResult(1, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE one").WithArgs("one").WillReturnResult(result) | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE two").WithArgs("one", "two").WillReturnResult(result) | 
					
						
							|  |  |  | 	mock.ExpectExec("^UPDATE three").WithArgs("one", "two", "three").WillReturnResult(result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var wg sync.WaitGroup | 
					
						
							|  |  |  | 	queries := map[string][]interface{}{ | 
					
						
							|  |  |  | 		"one":   []interface{}{"one"}, | 
					
						
							|  |  |  | 		"two":   []interface{}{"one", "two"}, | 
					
						
							|  |  |  | 		"three": []interface{}{"one", "two", "three"}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Add(len(queries)) | 
					
						
							|  |  |  | 	for table, args := range queries { | 
					
						
							|  |  |  | 		go func(tbl string, a []interface{}) { | 
					
						
							|  |  |  | 			if _, err := db.Exec("UPDATE "+tbl, a...); err != nil { | 
					
						
							|  |  |  | 				fmt.Println("error was not expected:", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			wg.Done() | 
					
						
							|  |  |  | 		}(table, args) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		fmt.Println("there were unfulfilled expectations:", err) | 
					
						
							| 
									
										
										
										
											2015-08-27 10:34:01 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Output: | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-26 14:38:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // False Positive - passes despite mismatched Exec | 
					
						
							|  |  |  | // see #37 issue | 
					
						
							|  |  |  | func TestRunExecsWithOrderedShouldNotMeetAllExpectations(t *testing.T) { | 
					
						
							|  |  |  | 	db, dbmock, _ := New() | 
					
						
							|  |  |  | 	dbmock.ExpectExec("THE FIRST EXEC") | 
					
						
							|  |  |  | 	dbmock.ExpectExec("THE SECOND EXEC") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, _ = db.Exec("THE FIRST EXEC") | 
					
						
							|  |  |  | 	_, _ = db.Exec("THE WRONG EXEC") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := dbmock.ExpectationsWereMet() | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("was expecting an error, but there wasn't any") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // False Positive - passes despite mismatched Exec | 
					
						
							|  |  |  | // see #37 issue | 
					
						
							|  |  |  | func TestRunQueriesWithOrderedShouldNotMeetAllExpectations(t *testing.T) { | 
					
						
							|  |  |  | 	db, dbmock, _ := New() | 
					
						
							| 
									
										
										
										
											2016-02-26 16:07:19 +00:00
										 |  |  | 	dbmock.ExpectQuery("THE FIRST QUERY") | 
					
						
							|  |  |  | 	dbmock.ExpectQuery("THE SECOND QUERY") | 
					
						
							| 
									
										
										
										
											2016-02-26 14:38:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-26 16:07:19 +00:00
										 |  |  | 	_, _ = db.Query("THE FIRST QUERY") | 
					
						
							|  |  |  | 	_, _ = db.Query("THE WRONG QUERY") | 
					
						
							| 
									
										
										
										
											2016-02-26 14:38:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err := dbmock.ExpectationsWereMet() | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Fatal("was expecting an error, but there wasn't any") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-26 16:07:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRunExecsWithExpectedErrorMeetsExpectations(t *testing.T) { | 
					
						
							|  |  |  | 	db, dbmock, _ := New() | 
					
						
							|  |  |  | 	dbmock.ExpectExec("THE FIRST EXEC").WillReturnError(fmt.Errorf("big bad bug")) | 
					
						
							|  |  |  | 	dbmock.ExpectExec("THE SECOND EXEC").WillReturnResult(NewResult(0, 0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, _ = db.Exec("THE FIRST EXEC") | 
					
						
							|  |  |  | 	_, _ = db.Exec("THE SECOND EXEC") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := dbmock.ExpectationsWereMet() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("all expectations should be met: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRunQueryWithExpectedErrorMeetsExpectations(t *testing.T) { | 
					
						
							|  |  |  | 	db, dbmock, _ := New() | 
					
						
							|  |  |  | 	dbmock.ExpectQuery("THE FIRST QUERY").WillReturnError(fmt.Errorf("big bad bug")) | 
					
						
							|  |  |  | 	dbmock.ExpectQuery("THE SECOND QUERY").WillReturnRows(NewRows([]string{"col"}).AddRow(1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, _ = db.Query("THE FIRST QUERY") | 
					
						
							|  |  |  | 	_, _ = db.Query("THE SECOND QUERY") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := dbmock.ExpectationsWereMet() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("all expectations should be met: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-22 22:26:18 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestEmptyRowSet(t *testing.T) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rs := NewRows([]string{"id", "title"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). | 
					
						
							|  |  |  | 		WithArgs(5). | 
					
						
							|  |  |  | 		WillReturnRows(rs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rows, err := db.Query("SELECT (.+) FROM articles WHERE id = ?", 5) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected while retrieving mock rows", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if er := rows.Close(); er != nil { | 
					
						
							|  |  |  | 			t.Error("Unexpected error while trying to close rows") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if rows.Next() { | 
					
						
							|  |  |  | 		t.Error("expected no rows but got one") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = mock.ExpectationsWereMet() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("all expectations should be met: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-11-02 14:49:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Based on issue #50 | 
					
						
							|  |  |  | func TestPrepareExpectationNotFulfilled(t *testing.T) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mock.ExpectPrepare("^BADSELECT$") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if _, err := db.Prepare("SELECT"); err == nil { | 
					
						
							|  |  |  | 		t.Fatal("prepare should not match expected query string") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err == nil { | 
					
						
							|  |  |  | 		t.Errorf("was expecting an error, since prepared statement query does not match, but there was none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestRollbackThrow(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// columns to be used for result | 
					
						
							|  |  |  | 	columns := []string{"id", "status"} | 
					
						
							|  |  |  | 	// expect transaction begin | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	// expect query to fetch order, match it with regexp | 
					
						
							|  |  |  | 	mock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE"). | 
					
						
							|  |  |  | 		WithArgs(1). | 
					
						
							|  |  |  | 		WillReturnRows(NewRows(columns).AddRow(1, 1)) | 
					
						
							|  |  |  | 	// expect transaction rollback, since order status is "cancelled" | 
					
						
							|  |  |  | 	mock.ExpectRollback().WillReturnError(fmt.Errorf("rollback failed")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// run the cancel order function | 
					
						
							|  |  |  | 	someOrderID := 1 | 
					
						
							|  |  |  | 	// call a function which executes expected database operations | 
					
						
							|  |  |  | 	err = cancelOrder(db, someOrderID) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when rolling back transaction, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ensure all expectations have been met | 
					
						
							|  |  |  | 	if err = mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-27 09:48:08 -05:00
										 |  |  | 		t.Errorf("unmet expectation error: %s", err) | 
					
						
							| 
									
										
										
										
											2016-11-22 18:42:07 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Output: | 
					
						
							| 
									
										
										
										
											2016-11-25 12:10:32 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnexpectedCommit(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	if err := tx.Commit(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling commit, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnexpectedCommitOrder(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							| 
									
										
										
										
											2016-11-27 09:48:08 -05:00
										 |  |  | 	mock.ExpectRollback().WillReturnError(fmt.Errorf("Rollback failed")) | 
					
						
							| 
									
										
										
										
											2016-11-25 12:10:32 -05:00
										 |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	if err := tx.Commit(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling commit, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-27 09:48:08 -05:00
										 |  |  | func TestExpectedCommitOrder(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectCommit().WillReturnError(fmt.Errorf("Commit failed")) | 
					
						
							|  |  |  | 	if _, err := db.Begin(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling begin, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-25 12:10:32 -05:00
										 |  |  | func TestUnexpectedRollback(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	if err := tx.Rollback(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling rollback, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestUnexpectedRollbackOrder(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-25 12:10:32 -05:00
										 |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	if err := tx.Rollback(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling rollback, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestPrepareExec(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	ep := mock.ExpectPrepare("INSERT INTO ORDERS\\(ID, STATUS\\) VALUES \\(\\?, \\?\\)") | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | 	for i := 0; i < 3; i++ { | 
					
						
							|  |  |  | 		ep.ExpectExec().WillReturnResult(NewResult(1, 1)) | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectCommit() | 
					
						
							|  |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	stmt, err := tx.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer stmt.Close() | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | 	for i := 0; i < 3; i++ { | 
					
						
							|  |  |  | 		_, err := stmt.Exec(i, "Hello"+strconv.Itoa(i)) | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	tx.Commit() | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestPrepareQuery(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 	mock.ExpectBegin() | 
					
						
							|  |  |  | 	ep := mock.ExpectPrepare("SELECT ID, STATUS FROM ORDERS WHERE ID = \\?") | 
					
						
							|  |  |  | 	ep.ExpectQuery().WithArgs(101).WillReturnRows(NewRows([]string{"ID", "STATUS"}).AddRow(101, "Hello")) | 
					
						
							|  |  |  | 	mock.ExpectCommit() | 
					
						
							|  |  |  | 	tx, _ := db.Begin() | 
					
						
							|  |  |  | 	stmt, err := tx.Prepare("SELECT ID, STATUS FROM ORDERS WHERE ID = ?") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer stmt.Close() | 
					
						
							|  |  |  | 	rows, err := stmt.Query(101) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer rows.Close() | 
					
						
							|  |  |  | 	for rows.Next() { | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | 		var ( | 
					
						
							|  |  |  | 			id     int | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 			status string | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		if rows.Scan(&id, &status); id != 101 || status != "Hello" { | 
					
						
							|  |  |  | 			t.Fatal("wrong query results") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	tx.Commit() | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2016-11-26 15:38:28 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-27 09:48:08 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestExpectedCloseError(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectClose().WillReturnError(fmt.Errorf("Close failed")) | 
					
						
							|  |  |  | 	if err := db.Close(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling close, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2016-11-27 09:48:08 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestExpectedCloseOrder(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 	mock.ExpectClose().WillReturnError(fmt.Errorf("Close failed")) | 
					
						
							|  |  |  | 	db.Begin() | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err == nil { | 
					
						
							|  |  |  | 		t.Error("expected error on ExpectationsWereMet") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestExpectedBeginOrder(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mock.ExpectBegin().WillReturnError(fmt.Errorf("Begin failed")) | 
					
						
							|  |  |  | 	if err := db.Close(); err == nil { | 
					
						
							|  |  |  | 		t.Error("an error was expected when calling close, but got none") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-04 18:09:50 +07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-01 10:24:02 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestPreparedStatementCloseExpectation(t *testing.T) { | 
					
						
							|  |  |  | 	// Open new mock database | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("error creating mock database") | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ep := mock.ExpectPrepare("INSERT INTO ORDERS").WillBeClosed() | 
					
						
							|  |  |  | 	ep.ExpectExec().WillReturnResult(NewResult(1, 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	stmt, err := db.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if _, err := stmt.Exec(1, "Hello"); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := stmt.Close(); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := mock.ExpectationsWereMet(); err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-25 09:32:15 -05:00
										 |  |  | 		t.Errorf("there were unfulfilled expectations: %s", err) | 
					
						
							| 
									
										
										
										
											2017-09-01 10:24:02 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-20 17:30:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestExecExpectationErrorDelay(t *testing.T) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 	db, mock, err := New() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer db.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test that return of error is delayed | 
					
						
							|  |  |  | 	var delay time.Duration | 
					
						
							|  |  |  | 	delay = 100 * time.Millisecond | 
					
						
							|  |  |  | 	mock.ExpectExec("^INSERT INTO articles"). | 
					
						
							|  |  |  | 		WillReturnError(errors.New("slow fail")). | 
					
						
							|  |  |  | 		WillDelayFor(delay) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	start := time.Now() | 
					
						
							|  |  |  | 	res, err := db.Exec("INSERT INTO articles (title) VALUES (?)", "hello") | 
					
						
							|  |  |  | 	stop := time.Now() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if res != nil { | 
					
						
							|  |  |  | 		t.Errorf("result was not expected, was expecting nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		t.Errorf("error was expected, was not expecting nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err.Error() != "slow fail" { | 
					
						
							|  |  |  | 		t.Errorf("error '%s' was not expected, was expecting '%s'", err.Error(), "slow fail") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	elapsed := stop.Sub(start) | 
					
						
							|  |  |  | 	if elapsed < delay { | 
					
						
							|  |  |  | 		t.Errorf("expecting a delay of %v before error, actual delay was %v", delay, elapsed) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// also test that return of error is not delayed | 
					
						
							|  |  |  | 	mock.ExpectExec("^INSERT INTO articles").WillReturnError(errors.New("fast fail")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	start = time.Now() | 
					
						
							|  |  |  | 	db.Exec("INSERT INTO articles (title) VALUES (?)", "hello") | 
					
						
							|  |  |  | 	stop = time.Now() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	elapsed = stop.Sub(start) | 
					
						
							|  |  |  | 	if elapsed > delay { | 
					
						
							|  |  |  | 		t.Errorf("expecting a delay of less than %v before error, actual delay was %v", delay, elapsed) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |