Sql mock driver for golang to test database interactions

Build Status GoDoc Go Report Card codecov.io

Sql driver mock for Golang

sqlmock is a mock library implementing sql/driver. Which has one and only purpose - to simulate any sql driver behavior in tests, without needing a real database connection. It helps to maintain correct TDD workflow.

  • this library is now complete and stable. (you may not find new changes for this reason)
  • supports concurrency and multiple connections.
  • supports go1.8 Context related feature mocking and Named sql parameters.
  • does not require any modifications to your source code.
  • the driver allows to mock any sql driver method behavior.
  • has strict by default expectation order matching.
  • has no third party dependencies.

NOTE: in v1.2.0 sqlmock.Rows has changed to struct from interface, if you were using any type references to that interface, you will need to switch it to a pointer struct type. Also, sqlmock.Rows were used to implement driver.Rows interface, which was not required or useful for mocking and was removed. Hope it will not cause issues.

Looking for maintainers

I do not have much spare time for this library and willing to transfer the repository ownership to person or an organization motivated to maintain it. Open up a conversation if you are interested. See #230.

Install

go get github.com/DATA-DOG/go-sqlmock

Documentation and Examples

Visit godoc for general examples and public api reference. See .travis.yml for supported go versions. Different use case, is to functionally test with a real database - go-txdb all database related actions are isolated within a single transaction so the database can remain in the same state.

See implementation examples:

Something you may want to test, assuming you use the go-mysql-driver

package main

import (
	"database/sql"

	_ "github.com/go-sql-driver/mysql"
)

func recordStats(db *sql.DB, userID, productID int64) (err error) {
	tx, err := db.Begin()
	if err != nil {
		return
	}

	defer func() {
		switch err {
		case nil:
			err = tx.Commit()
		default:
			tx.Rollback()
		}
	}()

	if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != nil {
		return
	}
	if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) VALUES (?, ?)", userID, productID); err != nil {
		return
	}
	return
}

func main() {
	// @NOTE: the real connection is not required for tests
	db, err := sql.Open("mysql", "root@/blog")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); err != nil {
		panic(err)
	}
}

Tests with sqlmock

package main

import (
	"fmt"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
)

// a successful case
func TestShouldUpdateStats(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	mock.ExpectBegin()
	mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
	mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))
	mock.ExpectCommit()

	// now we execute our method
	if err = recordStats(db, 2, 3); err != nil {
		t.Errorf("error was not expected while updating stats: %s", err)
	}

	// we make sure that all expectations were met
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("there were unfulfilled expectations: %s", err)
	}
}

// a failing test case
func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {
	db, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
	}
	defer db.Close()

	mock.ExpectBegin()
	mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
	mock.ExpectExec("INSERT INTO product_viewers").
		WithArgs(2, 3).
		WillReturnError(fmt.Errorf("some error"))
	mock.ExpectRollback()

	// now we execute our method
	if err = recordStats(db, 2, 3); err == nil {
		t.Errorf("was expecting an error, but there was none")
	}

	// we make sure that all expectations were met
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("there were unfulfilled expectations: %s", err)
	}
}

Customize SQL query matching

There were plenty of requests from users regarding SQL query string validation or different matching option. We have now implemented the QueryMatcher interface, which can be passed through an option when calling sqlmock.New or sqlmock.NewWithDSN.

This now allows to include some library, which would allow for example to parse and validate mysql SQL AST. And create a custom QueryMatcher in order to validate SQL in sophisticated ways.

By default, sqlmock is preserving backward compatibility and default query matcher is sqlmock.QueryMatcherRegexp which uses expected SQL string as a regular expression to match incoming query string. There is an equality matcher: QueryMatcherEqual which will do a full case sensitive match.

In order to customize the QueryMatcher, use the following:

	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))

The query matcher can be fully customized based on user needs. sqlmock will not provide a standard sql parsing matchers, since various drivers may not follow the same SQL standard.

Matching arguments like time.Time

There may be arguments which are of struct type and cannot be compared easily by value like time.Time. In this case sqlmock provides an Argument interface which can be used in more sophisticated matching. Here is a simple example of time argument matching:

type AnyTime struct{}

// Match satisfies sqlmock.Argument interface
func (a AnyTime) Match(v driver.Value) bool {
	_, ok := v.(time.Time)
	return ok
}

func TestAnyTimeArgument(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.ExpectExec("INSERT INTO users").
		WithArgs("john", AnyTime{}).
		WillReturnResult(NewResult(1, 1))

	_, err = db.Exec("INSERT INTO users(name, created_at) VALUES (?, ?)", "john", time.Now())
	if err != nil {
		t.Errorf("error '%s' was not expected, while inserting a row", err)
	}

	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("there were unfulfilled expectations: %s", err)
	}
}

It only asserts that argument is of time.Time type.

Run tests

go test -race

Change Log

  • 2019-04-06 - added functionality to mock a sql MetaData request
  • 2019-02-13 - added go.mod removed the references and suggestions using gopkg.in.
  • 2018-12-11 - added expectation of Rows to be closed, while mocking expected query.
  • 2018-12-11 - introduced an option to provide QueryMatcher in order to customize SQL query matching.
  • 2017-09-01 - it is now possible to expect that prepared statement will be closed, using ExpectedPrepare.WillBeClosed.
  • 2017-02-09 - implemented support for go1.8 features. Rows interface was changed to struct but contains all methods as before and should maintain backwards compatibility. ExpectedQuery.WillReturnRows may now accept multiple row sets.
  • 2016-11-02 - db.Prepare() was not validating expected prepare SQL query. It should still be validated even if Exec or Query is not executed on that prepared statement.
  • 2016-02-23 - added sqlmock.AnyArg() function to provide any kind of argument matcher.
  • 2016-02-23 - convert expected arguments to driver.Value as natural driver does, the change may affect time.Time comparison and will be stricter. See issue.
  • 2015-08-27 - v1 api change, concurrency support, all known issues fixed.
  • 2014-08-16 instead of panic during reflect type mismatch when comparing query arguments - now return error
  • 2014-08-14 added sqlmock.NewErrorResult which gives an option to return driver.Result with errors for interface methods, see issue
  • 2014-05-29 allow to match arguments in more sophisticated ways, by providing an sqlmock.Argument interface
  • 2014-04-21 introduce sqlmock.New() to open a mock database connection for tests. This method calls sql.DB.Ping to ensure that connection is open, see issue. This way on Close it will surely assert if all expectations are met, even if database was not triggered at all. The old way is still available, but it is advisable to call db.Ping manually before asserting with db.Close.
  • 2014-02-14 RowsFromCSVString is now a part of Rows interface named as FromCSVString. It has changed to allow more ways to construct rows and to easily extend this API in future. See issue 1 RowsFromCSVString is deprecated and will be removed in future

Contributions

Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) - please open an issue before, to discuss whether these changes can be accepted. All backward incompatible changes are and will be treated cautiously

License

The three clause BSD license

Owner
DATA-DOG
Happy awesome developers
DATA-DOG
Comments
  • introduce MockConn type, which represents isolated connections

    introduce MockConn type, which represents isolated connections

    Hi, this is an attempt to isolate connections for parallel testing. Coincidentally I had to solve this issue for myself as well.

    Since the sql.Open() does a whole lot more than just passing a driver.Conn I had to identify instances using IDs and passing them in the DSN.

    Should help with #9

  • INSERT while mocking gorm

    INSERT while mocking gorm

    I'm having a lot of trouble mocking gorm INSERT queries. I was able to get my tests passing when selecting fine, but I am running into this error when inserting.

    # Gorm's debug output
    INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ('2018-05-01 17:46:15','2018-05-01 17:46:15',NULL,'Group 1','A good group') RETURNING "groups"."id"
    
    # Error returned from *gorm.DB.Create
    2018/05/01 17:46:15 Error creating group: call to Query 'INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ($1,$2,$3,$4,$5) RETURNING "groups"."id"' with args [{Name: Ordinal:1 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:2 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:3 Value:<nil>} {Name: Ordinal:4 Value:Group 1} {Name: Ordinal:5 Value:A good group}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
      - matches sql: '^INSERT INTO "groups" (.+)$'
      - is with arguments:
        0 - {}
        1 - {}
        2 - <nil>
        3 - Group 1
        4 - A good group
      - should return Result having:
          LastInsertId: 1
          RowsAffected: 1
    

    I have tried multiple different versions of the regex, even tested the match using golang on regex101.com, but I can't seem to get my sqlmock to match gorm's insert.

    Here is my test:

    type AnyTime struct{} // I don't actually know if I even need this
    
    func (a AnyTime) Match(v driver.Value) bool {
    	_, ok := v.(time.Time)
    	return ok
    }
    
    func TestGroupService_Create(t *testing.T) {
    	db, mock, err := sqlmock.New()
    	if err != nil {
    		log.Fatalf("can't create sqlmock: %s", err)
    	}
    	models.DB, err = gorm.Open("postgres", db)
    	if err != nil {
    		log.Fatalf("can't open gorm connection: %s", err)
    	}
    	defer db.Close()
    
    	models.DB.LogMode(true)
    
    	name := "Group 1"
    	description := "A good group"
    
    	mock.ExpectExec("^INSERT INTO \"groups\" (.+)$").WithArgs(AnyTime{}, AnyTime{}, nil, name, description).WillReturnResult(sqlmock.NewResult(1, 1))
    
    	s := GroupService{}
    
    	req := &pb.CreateGroupRequest{
    		Name: name,
    		Description: description,
    	}
    
    	resp, err := s.Create(context.Background(), req)
    	assert.Nil(t, err)
    
    	if assert.NotNil(t, resp) {
    		assert.Equal(t, resp.Group.Name, name)
    		assert.Equal(t, resp.Group.Description, description)
    	}
    
    	err = mock.ExpectationsWereMet()
    	assert.Nil(t, err)
    }
    

    and my service method I'm trying to test:

    func (server *GroupService) Create(ctx context.Context, request *pb.CreateGroupRequest) (*pb.CreateGroupReply, error) {
    	var group models.Group
    
    	group.Name = request.Name
    	group.Description = request.Description
    
    	db := models.DB
    
    	if err := db.Create(&group).Error; err != nil {
    		log.Printf("Error creating group: %v", err)
    		return nil, err
    	}
    
    	createReply := pb.CreateGroupReply{
    		Group: mapGroupToService(group),
    	}
    
    	return &createReply, nil
    }
    

    I just can't seem to figure this out. Thanks!

  • No known way to fail on unexpected calls

    No known way to fail on unexpected calls

    I want to make sure the query executed when an expectation is not met is not executed. I looked but there does not seem to be any option to do a sqlMock.ExpectExec().Times(0) or a slMock.FailOnUnexpectedMatches(true) or sqlMock.FailOnExec(). Please let me know/ show me an example on how to work around this. We cannot test an important condition without it

  • v1.3.1 Breaks build

    v1.3.1 Breaks build

    Any idea what is going on here? This has been happening for us since the 1.3.1 release.

    go: finding gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.1
    go: gopkg.in/DATA-DOG/[email protected]: go.mod has non-....v1 module path "sqlmock" at revision v1.3.1
    
  • Rows does not implement database/sql/driver.Rows

    Rows does not implement database/sql/driver.Rows

    The new Rows struct is not backward compatible with the previous Rows interface; it's missing all of the driver.Rows methods. T

    he changelog and commit message from #68 leads one to believe that was an inadvertent change.

  • Expectations are not met

    Expectations are not met

    Hi,

    i am mocking a insert statement but the expectation fails, event though i cannot see why. The following error message reveal that the arguments are identical.

    sql_writer_test.go:29: error was not expected while writing event: exec query 'INSERT INTO Event (SourceId, Created, EventType, Version, Payload) VALUES (?, ?, ?, ?, ?)', args [2eb5880e-4bfd-4450-92fc-df851bae5dbb 2016-02-03 22:05:00.712109 +0000 UTC TEST 1 {"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}] does not match expected [2eb5880e-4bfd-4450-92fc-df851bae5dbb 2016-02-03 22:05:00.712109 +0000 UTC TEST 1 {"version":1,"name":"Joe","balance":12.99,"birth_date":"2015-12-13T23:59:59+02:00"}]

    Am i doing something wrong?

  • latest go-sqlmock(v1.3.3) and gorm(v1.9.11) version incompatible

    latest go-sqlmock(v1.3.3) and gorm(v1.9.11) version incompatible

    Use gorm-ut source with upgrade deps version, go.mod:

    module github.com/Rosaniline/gorm-ut
    
    go 1.13
    
    require (
    	github.com/DATA-DOG/go-sqlmock v1.3.3
    	github.com/go-test/deep v1.0.4
    	github.com/jinzhu/gorm v1.9.11
    	github.com/satori/go.uuid v1.2.0
    	github.com/stretchr/testify v1.4.0
    )
    

    and run test, command line shows:

    ?[35m(C:/Users/ping/Desktop/gorm-ut-master/pkg/repository/person.go:24)?[0m
    ?[33m[2019-10-21 15:52:57]?[0m ?[31;1m call to database transaction Begin, was not expected, next expectation is: ExpectedQuery => expecting Query, QueryContext or QueryRow which:
      - matches sql: 'INSERT INTO "person" \("id","name"\)
                            VALUES \(\$1,\$2\) RETURNING "person"\."id"'
      - is with arguments:
        0 - c34a302e-bc5d-4e3d-8104-680ca2a438bb
        1 - test-name
      - should return rows:
        row 0 - [c34a302e-bc5d-4e3d-8104-680ca2a438bb] ?[0m
    
    ?[35m(C:/Users/ping/Desktop/gorm-ut-master/pkg/repository/person.go:30)?[0m
    ?[33m[2019-10-21 15:52:57]?[0m ?[31;1m Query: could not match actual sql: "SELECT * FROM "person" WHERE (id = ?)" with expected regexp "INSERT INTO "person" \("id","name"\) VALUES \(\$
    1,\$2\) RETURNING "person"\."id"" ?[0m
    
    ?[35m(C:/Users/ping/Desktop/gorm-ut-master/pkg/repository/person.go:30)?[0m
    ?[33m[2019-10-21 15:52:57]?[0m  ?[36;1m[0.00ms]?[0m  SELECT * FROM "person"  WHERE (id = 'd5328d68-8664-4aab-ad92-8b74e3010ea8')
    ?[36;31m[0 rows affected or returned ]?[0m
    --- FAIL: TestInit (0.01s)
        --- FAIL: TestInit/Test_repository_Create (0.01s)
            person_test.go:85:
                    Error Trace:    person_test.go:85
                    Error:          Received unexpected error:
                                    call to database transaction Begin, was not expected, next expectation is: ExpectedQuery => expecting Query, QueryContext or QueryRow which:
                                      - matches sql: 'INSERT INTO "person" \("id","name"\)
                                                            VALUES \(\$1,\$2\) RETURNING "person"\."id"'
                                      - is with arguments:
                                        0 - c34a302e-bc5d-4e3d-8104-680ca2a438bb
                                        1 - test-name
                                      - should return rows:
                                        row 0 - [c34a302e-bc5d-4e3d-8104-680ca2a438bb]
                    Test:           TestInit/Test_repository_Create
            person_test.go:45:
                    Error Trace:    person_test.go:45
                                                            suite.go:126
                                                            panic.go:563
                                                            testing.go:653
                                                            person_test.go:85
                    Error:          Received unexpected error:
                                    there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:
                                      - matches sql: 'INSERT INTO "person" \("id","name"\)
                                                            VALUES \(\$1,\$2\) RETURNING "person"\."id"'
                                      - is with arguments:
                                        0 - c34a302e-bc5d-4e3d-8104-680ca2a438bb
                                        1 - test-name
                                      - should return rows:
                                        row 0 - [c34a302e-bc5d-4e3d-8104-680ca2a438bb]
                    Test:           TestInit/Test_repository_Create
        --- FAIL: TestInit/Test_repository_Get (0.00s)
            person_test.go:66:
                    Error Trace:    person_test.go:66
                    Error:          Received unexpected error:
                                    Query: could not match actual sql: "SELECT * FROM "person" WHERE (id = ?)" with expected regexp "INSERT INTO "person" \("id","name"\) VALUES \(\$1,\$2\)
     RETURNING "person"\."id""
                    Test:           TestInit/Test_repository_Get
            person_test.go:45:
                    Error Trace:    person_test.go:45
                                                            suite.go:126
                                                            panic.go:563
                                                            testing.go:653
                                                            person_test.go:66
                    Error:          Received unexpected error:
                                    there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:
                                      - matches sql: 'INSERT INTO "person" \("id","name"\)
                                                            VALUES \(\$1,\$2\) RETURNING "person"\."id"'
                                      - is with arguments:
                                        0 - c34a302e-bc5d-4e3d-8104-680ca2a438bb
                                        1 - test-name
                                      - should return rows:
                                        row 0 - [c34a302e-bc5d-4e3d-8104-680ca2a438bb]
                    Test:           TestInit/Test_repository_Get
    FAIL
    FAIL    github.com/Rosaniline/gorm-ut/pkg/repository    0.345s
    FAIL
    

    If not upgrade deps, keep it with origin repo, it works.

  • concurrency support, closes #20 and closes #9 and closes #15

    concurrency support, closes #20 and closes #9 and closes #15

    After some use cases and

    Refactor to support concurrency and multiple connections per mock database instance. When this branch will be merged, there will be BC break and a new major version bump.

    Solves the following issues:

    • [x] parallel tests, any number of mock databases, closes #9 extends and closes #10
    • [x] since rows holds a connection reserved, allow to open any number of connections, closes #20
    • [x] allow to expect database close to be called, closes #15
    • [x] more expectations, for example allow for rows to return error at any point. closes #13
    • [x] deprecated methods: RowsFromCSVString will be removed
    • [x] allow unordered expectation matching, support for goroutines, see test.
    • [x] all possible places where values may be changed, should be available for mocking.
    • [x] more expressive errors
    • [x] documentation updated
    • [x] allow null values from csv string to be converted to nil. closes #22
  • Implement ExpectPings to watch for Ping attempts on the database

    Implement ExpectPings to watch for Ping attempts on the database

    Implemented an ExpectPing method to watch for calls to Ping on the driver.

    Some complexity: Ping is used on open to drive internal sql library behaviour to open a connection. We don't want these pings to be treated as expectations so there's a mechanism to override this checking in some cases.

    In order to neatly implement the behaviour without duplicating the Sqlmock interface, the ExpectPing method is installed in the mock in all Go versions, but does nothing in pre-1.8 instances.

  • Add support for repeatable assertions.

    Add support for repeatable assertions.

    Implements #82.

    The syntax looks like:

    	mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
    		WithArgs(5).
    		WillReturnRows(rs).
    		AnyNumberOfTimes()
    

    My specific use case is testing some polling APIs that might run any number of times during the test based on exact timing, but this seemed like a generally useful thing to have :-)

  • Added join and expectations functions to the sqlmock interface.

    Added join and expectations functions to the sqlmock interface.

    I have added two new functions to the sqlmock interface:

    • Expectations() []expectation
    • Join(sqlmock Sqlmock)

    This means you can now predefine mocks and reuse them as per the next example.

    func MockFindTweeter() (*sql.DB, sqlmock.Sqlmock, error) {
    
    	db, mock, err := sqlmock.New()
    	if err != nil {
    		return nil, nil, err
    	}
    
    	mock.ExpectPrepare("FIND (.+) FROM tweeters").
    		ExpectQuery().
    		WithArgs(tweeterID).
    		WillReturnRows(TweeterRows())
    
    	return db, mock, nil
    }
    
    func MockFindTweets() (*sql.DB, sqlmock.Sqlmock, error) {
    
    	db, mock, err := sqlmock.New()
    	if err != nil {
    		return nil, nil, err
    	}
    
    	mock.ExpectPrepare("FIND (.+) FROM tweets").
    		ExpectQuery().
    		WithArgs(tweeterID).
    		WillReturnRows(TweetRows())
    
    	return db, mock, nil
    }
    
    db, mock, err := database.MockFindTweeter()
    if err != nil {
    	t.Fatal(err)
    }
    
    _, mockFindTweets, err := database.MockFindTweets()
    if err != nil {
    	t.Fatal(err)
    }
    
    mock.Join(mockFindTweets)
    
    

    I would have preferred to have just been able to access sqlmock.expectations directly. Im not sure what the reasoning is for not exporting expectations or the expectations interface.

  • please provide GORM example

    please provide GORM example

    Hi there,

    Hope you are well today.

    Great work done here, really appreciated!

    Wondering if you could possibly add an example about how to implement it in GORM?

    I found some examples, though it'd be great come here only to see some examples about it.

    Regards, Julio

  • Added SqlMock type to allow for options to be sent to function that creates the sqlmock

    Added SqlMock type to allow for options to be sent to function that creates the sqlmock

    This PR addresses an issue where the user wants to embed the SqlMock creation code into a function, like so:

    func createServiceMock(database string, schema string, opts ...sqlmock.SqlMockOption) (*MyDB, sqlmock.Sqlmock) {
    
    	db, mock, err := sqlmock.New(opts...)
    	Expect(err).ShouldNot(HaveOccurred())
    
    	svc := FromConnection(database, schema, db)
    
    	return svc, mock
    }
    

    With the current implementation of go-sqlmock, this cannot done because the option references a type internal to the go-sqlmock package. By adding an alias for this type, the user can now send such options without exposing the internal sqlmock type.

  • gordor.options  PrefetchCount\FetchArraySize

    gordor.options PrefetchCount\FetchArraySize

    Hi, i am trying to mock with this code, request with gordor PrefetchCount\FetchArraySize params. refDestMockRows := sqlmock.NewRows([]string{"code", "ipcd_id"}). AddRow("3333", 33). AddRow("4444", 44). AddRow("3434", 33) mock.ExpectQuery(sqlDSTRQuery).WillReturnRows(refDestMockRows)

    query rows, err := tx.QueryContext(ctx, sqlDSTRQuery, godror.PrefetchCount(preFetchSize), godror.FetchArraySize(fetchSize))

    and receive an error sql: converting argument $1 type: unsupported type godror.Option, a func

    if i remove godror.PrefetchCount(preFetchSize), godror.FetchArraySize(fetchSize) everything become fine, but it's not an option. Please tell me what I'm doing wrong.

  • Getting 'Query: could not match actual sql' on identical queries

    Getting 'Query: could not match actual sql' on identical queries

    Operating system and Go Version

    • OS: macOS Ventura 13.0 (22A380)
    • System: Macbook Apple M1 Air
    • go version: go1.16.15 darwin/arm64 (Tried with go1.18.2 darwin/arm64 & go1.19 darwin/arm64 as well)
    • go-sqlmock: v1.5.0

    Issue

    Getting error "Query: could not match actual sql" even though both strings are identical. (compared via another tool)

    rows, err := d.DB.Query(query)
    

    P.S:: Same code is working on other systems. Not sure whether its related to different hardware architecture or OS.

    Reproduction steps

    SQL query is mocked like this:

    mock.ExpectQuery(regexp.QuoteMeta(expectedQuery)).WillReturnRows(rows)
    

    Expected Result

    There should be no error.

    Actual Result

    Query: could not match actual sql:

  • Add WillCompleteOnCancel expectation

    Add WillCompleteOnCancel expectation

    Closes #299

    I nerd-sniped myself after writing up the issue and started looking into the code. Turned out to be pretty straight-forward. So here's a PR! I hope you think it's useful. If you decide to merge this I would certainly pull this update and use this feature to write some new tests.

    The goal of .WillCompleteOnCancel() is to be able to test a pretty rare edge case in Postgres (and maybe other databases?) where the Go context is cancelled but due to timing, may not succeed in actually cancelling the query. In this case the query completes without error, and functions like QueryContext() et al. do not return the "context canceled" error we normally expect.

    This change is fully backward-compatible. There is no change to the default behavior which is to return ErrCancelled when the context is cancelled.

CLI tool to mock TCP connections. You can use it with Detox, Cypress or any other framework to automatically mock your backend or database.

Falso It is a CLI that allows you to mock requests/responses between you and any server without any configuration or previous knowledge about how it w

Sep 23, 2022
A Go implementation of Servirtium, a library that helps test interactions with APIs.

Servirtium is a server that serves as a man-in-the-middle: it processes incoming requests, forwards them to a destination API and writes the response into a Markdown file with a special format that is common across all of the implementations of the library.

Jun 16, 2022
Vault mock - Mock of Hashicorp Vault used for unit testing

vault_mock Mock of Hashicorp Vault used for unit testing Notice This is a person

Jan 19, 2022
Mock-the-fck - Mock exercise for human

Mock the fck Originally, Mockery-example Example case for mockery issue #128 fil

Jan 21, 2022
Record and replay your HTTP interactions for fast, deterministic and accurate tests

go-vcr go-vcr simplifies testing by recording your HTTP interactions and replaying them in future runs in order to provide fast, deterministic and acc

Dec 25, 2022
Go-interactions - Easy slash commands for Arikawa

go-interactions A library that aims to make dealing with discord's slash command

May 26, 2022
A tool that integrates SQL, HTTP,interface,Redis mock

Mockit 目标:将mock变得简单,让代码维护变得容易 分支介绍 main 主分支,覆盖了单元测试 light 轻分支,去除了单元测试,简化了依赖项,方便其他团队使用 常见Mock难点 不同中间件,mock库设计模式不一致,学习代价高,差异化明显 mock方案强依赖服务端,无法灵活解耦 单元测试

Sep 22, 2022
Immutable transaction isolated sql driver for golang

Single transaction based sql.Driver for GO Package txdb is a single transaction based database sql driver. When the connection is opened, it starts a

Jan 6, 2023
Test-assignment - Test assignment with golang
Test-assignment - Test assignment with golang

test-assignment We have a two steam of data and we need to save it in the map: I

Jan 19, 2022
go-test-trace is like go test but it also generates distributed traces.
go-test-trace is like go test but it also generates distributed traces.

go-test-trace go-test-trace is like go test but it also generates distributed traces. Generated traces are exported in OTLP to a OpenTelemetry collect

Jan 5, 2023
Flugel Test Documentation for steps to run and test the automatio
Flugel Test Documentation for steps to run and test the automatio

Flugel Test Documentation Documentation for steps to run and test the automation #Test-01 1 - Local Test Using Terratest (End To End) 1- By runing " t

Nov 13, 2022
This repository includes consumer driven contract test for provider, unit test and counter api.

This repository includes consumer driven contract test for provider, unit test and counter api.

Feb 1, 2022
mockery - A mock code autogenerator for Golang
mockery - A mock code autogenerator for Golang

mockery - A mock code autogenerator for Golang

Jan 8, 2023
Just Dance Unlimited mock-up server written on Golang and uses a popular Gin framework for Go.

BDCS Just Dance Unlimited mock-up server written on Golang and uses a popular Gin framework for Go. Features Security Authorization works using UbiSer

Nov 10, 2021
A simple mock server configurable via JSON, built using GoLang.
A simple mock server configurable via JSON, built using GoLang.

GoMock Server A simple mock server configurable via JSON, built using GoLang. How To A file name endpoint.json must be placed in the context root, wit

Nov 19, 2022
Grpcmock - Mock grpc server with golang

grpcmock Mock gRPC server. Inspired by Prism. Add example responses to your prot

May 8, 2022
Powerful mock generation tool for Go programming language

Summary Minimock generates mocks out of Go interface declarations. The main features of minimock are: It generates statically typed mocks and helpers.

Dec 17, 2022
Mock object for Go http.ResponseWriter

mockhttp -- Go package for unit testing HTTP serving Unit testing HTTP services written in Go means you need to call their ServeHTTP receiver. For thi

Sep 27, 2022
ESME is a go library that allows you to mock a RESTful service by defining the configuration in json format

ESME is a go library that allows you to mock a RESTful service by defining the configuration in json format. This service can then simply be consumed by any client to get the expected response.

Mar 2, 2021