### Install pgxmock Source: https://context7.com/pashagolub/pgxmock/llms.txt Install the pgxmock library using go get. ```bash go get github.com/pashagolub/pgxmock/v5 ``` -------------------------------- ### Example pgx Functionality Source: https://github.com/pashagolub/pgxmock/blob/master/README.md This Go code demonstrates a function that interacts with a PostgreSQL database using the pgx driver, including transaction management and data manipulation. It is intended to be tested using a mock. ```go package main import ( "context" pgx "github.com/jackc/pgx/v5" ) type PgxIface interface { Begin(context.Context) (pgx.Tx, error) Close(context.Context) error } func recordStats(db PgxIface, userID, productID int) (err error) { if tx, err := db.Begin(context.Background()); err != nil { return } defer func() { switch err { case nil: err = tx.Commit(context.Background()) default: _ = tx.Rollback(context.Background()) } }() sql := "UPDATE products SET views = views + 1" if _, err = tx.Exec(context.Background(), sql); err != nil { return } sql = "INSERT INTO product_viewers (user_id, product_id) VALUES ($1, $2)" if _, err = tx.Exec(context.Background(), sql, userID, productID); err != nil { return } return } func main() { // @NOTE: the real connection is not required for tests db, err := pgx.Connect(context.Background(), "postgres://rolname@hostname/dbname") if err != nil { panic(err) } defer db.Close(context.Background()) if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); err != nil { panic(err) } } ``` -------------------------------- ### Implement AnyTime Argument Matcher Source: https://github.com/pashagolub/pgxmock/blob/master/README.md Define a custom Argument type to match time.Time values. This example checks if the argument is of type time.Time. ```go type AnyTime struct{} // Match satisfies sqlmock.Argument interface func (a AnyTime) Match(v interface{}) bool { _, ok := v.(time.Time) return ok } ``` -------------------------------- ### Create Mock Connection Pool Source: https://context7.com/pashagolub/pgxmock/llms.txt Create a mock connection pool implementing the PgxPoolIface for testing code that uses pgxpool.Pool. Ensure to close the mock pool when done. ```go package main import ( "testing" "github.com/pashagolub/pgxmock/v5" ) func TestWithPool(t *testing.T) { mock, err := pgxmock.NewPool() if err != nil { t.Fatal(err) } defer mock.Close() // Set up expectations and run tests mock.ExpectPing() // Verify all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Create Mock Single Connection Source: https://context7.com/pashagolub/pgxmock/llms.txt Create a mock single connection implementing the PgxConnIface for testing code that uses pgx.Conn. Ensure to close the mock connection with a background context. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestWithConn(t *testing.T) { mock, err := pgxmock.NewConn() if err != nil { t.Fatal(err) } defer mock.Close(context.Background()) // Set up expectations and run tests mock.ExpectPing() // Verify all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Test Time Argument Matching with pgxmock Source: https://github.com/pashagolub/pgxmock/blob/master/README.md Demonstrates using a custom Argument (AnyTime) to match time.Time values during query execution. Ensure all expectations are met after execution. ```go 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) } } ``` -------------------------------- ### Expect Query with Specific Arguments Source: https://context7.com/pashagolub/pgxmock/llms.txt Use WithArgs() to match specific query arguments. Arguments are matched in order using deep equality or custom matchers. Ensure the query is executed with matching arguments. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestQueryWithArgs(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) rows := mock.NewRows([]string{"id", "name", "email"}). AddRow(42, "John Doe", "john@example.com") // Expect query with specific arguments mock.ExpectQuery("SELECT (.+) FROM users WHERE id = \\$1"). WithArgs(42). WillReturnRows(rows) // Execute query with matching arguments row := mock.QueryRow(context.Background(), "SELECT id, name, email FROM users WHERE id = $1", 42) var id int var name, email string if err := row.Scan(&id, &name, &email); err != nil { t.Fatal(err) } // id=42, name="John Doe", email="john@example.com" if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Mock Prepared Statements and Deallocation in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt Use `mock.ExpectPrepare()` and `mock.ExpectDeallocate()` to mock the creation and deallocation of prepared statements. This is essential for testing code that relies on prepared statements. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestPreparedStatements(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect prepare with statement name and SQL mock.ExpectPrepare("get_user", "SELECT (.+) FROM users WHERE id = \$1") mock.ExpectDeallocate("get_user") // Prepare statement stmt, err := mock.Prepare(context.Background(), "get_user", "SELECT id, name FROM users WHERE id = $1") if err != nil { t.Fatal(err) } // stmt.Name == "get_user" // Deallocate statement mock.Deallocate(context.Background(), "get_user") if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Build Mock Rows with AddRow Source: https://context7.com/pashagolub/pgxmock/llms.txt Construct mock query results by first creating a row set with NewRows, specifying column names, and then chaining AddRow calls for each row of data. This method is suitable for adding rows individually. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestBuildRows(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Build rows with multiple AddRow calls rows := mock.NewRows([]string{"id", "name", "active", "balance"}). AddRow(1, "Alice", true, 100.50). AddRow(2, "Bob", false, 0.0). AddRow(3, "Charlie", true, 250.75) mock.ExpectQuery("SELECT").WillReturnRows(rows) result, _ := mock.Query(context.Background(), "SELECT id, name, active, balance FROM accounts") defer result.Close() count := 0 for result.Next() { var id int var name string var active bool var balance float64 result.Scan(&id, &name, &active, &balance) count++ } // count == 3 if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect Query and Return Rows Source: https://context7.com/pashagolub/pgxmock/llms.txt Expect a Query() or QueryRow() call with a SQL pattern (regex by default). Use WillReturnRows() to define the mock rows to be returned. Ensure all expectations are met after execution. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestQueryRows(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Create mock rows with column definitions rows := mock.NewRows([]string{"id", "title", "body"}). AddRow(1, "Post 1", "Hello World"). AddRow(2, "Post 2", "Testing pgxmock") // Expect SELECT query with regex pattern mock.ExpectQuery("^SELECT (.+) FROM posts$"). WillReturnRows(rows) // Execute the query result, err := mock.Query(context.Background(), "SELECT id, title, body FROM posts") if err != nil { t.Fatal(err) } defer result.Close() // Iterate through results for result.Next() { var id int var title, body string if err := result.Scan(&id, &title, &body); err != nil { t.Fatal(err) } t.Logf("Post %d: %s - %s", id, title, body) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Simulate Latency with WillDelayFor Source: https://context7.com/pashagolub/pgxmock/llms.txt Use WillDelayFor(duration) to simulate network latency or slow query execution. This delays the mocked response by the specified duration. ```go package main import ( "context" "testing" "time" "github.com/pashagolub/pgxmock/v5" ) func TestDelayedResponse(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Simulate slow query mock.ExpectQuery("SELECT"). WillDelayFor(100 * time.Millisecond). WillReturnRows(mock.NewRows([]string{"id"}).AddRow(1)) start := time.Now() mock.Query(context.Background(), "SELECT id FROM slow_table") elapsed := time.Since(start) if elapsed < 100*time.Millisecond { t.Error("expected delay of at least 100ms") } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect Successful Ping in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt Use `mock.ExpectPing()` to set up an expectation for a successful `Ping()` call. This is useful for testing connection health check logic. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestPing(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect successful ping mock.ExpectPing() err := mock.Ping(context.Background()) if err != nil { t.Fatal(err) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect BeginTx with Specific Options Source: https://context7.com/pashagolub/pgxmock/llms.txt Use ExpectBeginTx to set expectations for a BeginTx call with specific transaction options, such as isolation level. Ensure to pair this with ExpectCommit if the transaction is expected to be committed. ```go package main import ( "context" "testing" "github.com/jackc/pgx/v5" "github.com/pashagolub/pgxmock/v5" ) func TestBeginTxWithOptions(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect transaction with specific isolation level txOpts := pgx.TxOptions{ IsoLevel: pgx.Serializable, } mock.ExpectBeginTx(txOpts) mock.ExpectCommit() // Begin transaction with matching options tx, err := mock.BeginTx(context.Background(), txOpts) if err != nil { t.Fatal(err) } tx.Commit(context.Background()) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Configure Exact Query Matching in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt Use `pgxmock.QueryMatcherOption(pgxmock.QueryMatcherEqual)` to enforce exact string matching for SQL queries, disabling regex matching. This requires queries to match precisely, ignoring only whitespace differences. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestQueryMatcherEqual(t *testing.T) { // Use exact string matching instead of regex mock, _ := pgxmock.NewConn(pgxmock.QueryMatcherOption(pgxmock.QueryMatcherEqual)) defer mock.Close(context.Background()) // Must match exactly (whitespace normalized) mock.ExpectQuery("SELECT id, name FROM users WHERE active = true"). WillReturnRows(mock.NewRows([]string{"id", "name"})) mock.Query(context.Background(), "SELECT id, name FROM users WHERE active = true") if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Customize QueryMatcher with QueryMatcherEqual Source: https://github.com/pashagolub/pgxmock/blob/master/README.md Use QueryMatcherOption to set a custom query matcher. QueryMatcherEqual performs a full case-sensitive match. ```go mock, err := pgxmock.New(context.Background(), pgxmock.QueryMatcherOption(pgxmock.QueryMatcherEqual)) ``` -------------------------------- ### Mock Transaction Lifecycle Source: https://context7.com/pashagolub/pgxmock/llms.txt Mock transaction lifecycle methods for testing code that uses database transactions. Covers successful commits and rollbacks due to errors. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestTransactionSuccess(t *testing.T) { mock, _ := pgxmock.NewPool() defer mock.Close() // Expect successful transaction mock.ExpectBegin() mock.ExpectExec("UPDATE products SET views = views \+ 1"). WillReturnResult(pgxmock.NewResult("UPDATE", 1)) mock.ExpectExec("INSERT INTO product_viewers"). WithArgs(2, 3). WillReturnResult(pgxmock.NewResult("INSERT", 1)) mock.ExpectCommit() // Execute transaction tx, _ := mock.Begin(context.Background()) tx.Exec(context.Background(), "UPDATE products SET views = views + 1") tx.Exec(context.Background(), "INSERT INTO product_viewers (user_id, product_id) VALUES ($1, $2)", 2, 3) tx.Commit(context.Background()) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestTransactionRollback(t *testing.T) { mock, _ := pgxmock.NewPool() defer mock.Close() // Expect transaction that fails and rolls back mock.ExpectBegin() mock.ExpectExec("UPDATE products"). WillReturnResult(pgxmock.NewResult("UPDATE", 1)) mock.ExpectExec("INSERT INTO product_viewers"). WithArgs(2, 3). WillReturnError(fmt.Errorf("foreign key violation")) mock.ExpectRollback() // Execute transaction with error tx, _ := mock.Begin(context.Background()) tx.Exec(context.Background(), "UPDATE products SET views = views + 1") _, err := tx.Exec(context.Background(), "INSERT INTO product_viewers (user_id, product_id) VALUES ($1, $2)", 2, 3) if err != nil { tx.Rollback(context.Background()) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Build Mock Rows from CSV String Source: https://context7.com/pashagolub/pgxmock/llms.txt Populate mock query results from a CSV-formatted string using FromCSVString. This method supports NULL values, which should be represented as the string "NULL" in the CSV data. It's a convenient way to define test data quickly. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestFromCSV(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Build rows from CSV string (NULL values supported) rows := mock.NewRows([]string{"id", "name", "email"}). FromCSVString( "\n1,Alice,alice@example.com\n2,Bob,NULL\n3,Charlie,charlie@example.com\n" ) mock.ExpectQuery("SELECT").WillReturnRows(rows) result, _ := mock.Query(context.Background(), "SELECT id, name, email FROM users") defer result.Close() for result.Next() { var id int var name string var email interface{} result.Scan(&id, &name, &email) // Row 2 will have email == nil } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Implement Custom Argument Matcher in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt Implement the `Argument` interface to define custom logic for matching function arguments. Use this when default matchers are insufficient. ```go package main import ( "context" "testing" "time" "github.com/pashagolub/pgxmock/v5" ) // AnyTime matches any time.Time value type AnyTime struct{} func (a AnyTime) Match(v interface{}) bool { _, ok := v.(time.Time) return ok } // RecentTime matches time.Time values within the last hour type RecentTime struct{} func (r RecentTime) Match(v interface{}) bool { t, ok := v.(time.Time) if !ok { return false } return time.Since(t) < time.Hour } func TestCustomArgMatcher(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Use custom matcher for time argument mock.ExpectExec("INSERT INTO users"). WithArgs("john", AnyTime{}). WillReturnResult(pgxmock.NewResult("INSERT", 1)) mock.Exec(context.Background(), "INSERT INTO users (name, created_at) VALUES ($1, $2)", "john", time.Now()) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Simulate Query Errors with WillReturnError Source: https://context7.com/pashagolub/pgxmock/llms.txt Use `WillReturnError()` to simulate query failures. This is useful for testing how your application handles database connection issues or other query-related errors. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestQueryError(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect query that returns an error mock.ExpectQuery("SELECT (.+) FROM posts"). WillReturnError(fmt.Errorf("connection lost")) // Execute query - should return error _, err := mock.Query(context.Background(), "SELECT id FROM posts") if err == nil { t.Error("expected error, got nil") } // err.Error() == "connection lost" if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Add Multiple Mock Rows with AddRows Source: https://context7.com/pashagolub/pgxmock/llms.txt Efficiently add multiple rows to a mock result set at once using the AddRows method, which accepts a slice of slices, where each inner slice represents a row's values. This is useful for populating mock data from a predefined list. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestAddMultipleRows(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Add multiple rows at once rows := mock.NewRows([]string{"id", "name"}). AddRows( []any{1, "Alice"}, []any{2, "Bob"}, []any{3, "Charlie"}, ) mock.ExpectQuery("SELECT").WillReturnRows(rows) result, _ := mock.Query(context.Background(), "SELECT id, name FROM users") defer result.Close() var users []string for result.Next() { var id int var name string result.Scan(&id, &name) users = append(users, name) } // users == ["Alice", "Bob", "Charlie"] if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Create CommandTag Results with NewResult Source: https://context7.com/pashagolub/pgxmock/llms.txt Creates a `pgconn.CommandTag` result for `ExpectedExec.WillReturnResult()`. Takes an operation name and rows affected count. Useful for simulating different DML operations. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestNewResult(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Different result types mock.ExpectExec("INSERT INTO products"). WillReturnResult(pgxmock.NewResult("INSERT", 1)) mock.ExpectExec("UPDATE products"). WillReturnResult(pgxmock.NewResult("UPDATE", 5)) mock.ExpectExec("DELETE FROM products"). WillReturnResult(pgxmock.NewResult("DELETE", 3)) // Execute statements mock.Exec(context.Background(), "INSERT INTO products (name) VALUES ($1)", "Widget") mock.Exec(context.Background(), "UPDATE products SET price = 10") mock.Exec(context.Background(), "DELETE FROM products WHERE obsolete = true") if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Use AnyArg Matcher for Arguments Source: https://context7.com/pashagolub/pgxmock/llms.txt Employ the AnyArg matcher when the exact value of an argument in a query or execution does not matter or is unpredictable, such as a timestamp. This allows the mock to match the call regardless of the specific value passed. ```go package main import ( "context" "testing" "time" "github.com/pashagolub/pgxmock/v5" ) func TestAnyArgMatcher(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Match any value for the timestamp argument mock.ExpectExec("INSERT INTO events"). WithArgs("login", pgxmock.AnyArg()). WillReturnResult(pgxmock.NewResult("INSERT", 1)) // Execute with current time (unpredictable value) mock.Exec(context.Background(), "INSERT INTO events (type, timestamp) VALUES ($1, $2)", "login", time.Now()) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect Batch Operation Source: https://context7.com/pashagolub/pgxmock/llms.txt Use ExpectBatch to mock a batch of SQL operations. It allows setting expectations for individual queries within the batch. ```go package main import ( "context" "testing" "github.com/jackc/pgx/v5" "github.com/pashagolub/pgxmock/v5" ) func TestBatch(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Set up batch expectations expectedBatch := mock.ExpectBatch() expectedBatch.ExpectExec("INSERT INTO users"). WithArgs("alice"). WillReturnResult(pgxmock.NewResult("INSERT", 1)) expectedBatch.ExpectQuery("SELECT id FROM users"). WillReturnRows(mock.NewRows([]string{"id"}).AddRow(1)) // Create and send batch batch := &pgx.Batch{} batch.Queue("INSERT INTO users (name) VALUES ($1)", "alice") batch.Queue("SELECT id FROM users WHERE name = 'alice'") results := mock.SendBatch(context.Background(), batch) defer results.Close() // Get exec result _, err := results.Exec() if err != nil { t.Fatal(err) } // Get query result rows, err := results.Query() if err != nil { t.Fatal(err) } rows.Close() if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Use Default Regex Query Matching in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt The default query matching behavior in pgxmock uses regular expressions. This allows for flexible matching of SQL queries against patterns. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestQueryMatcherRegexp(t *testing.T) { // Default regex matching mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Regex pattern matching mock.ExpectQuery("SELECT .+ FROM users WHERE id = \$1"). WithArgs(1). WillReturnRows(mock.NewRows([]string{"id", "name"})) mock.Query(context.Background(), "SELECT id, name, email FROM users WHERE id = $1", 1) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect Exec for DML Statements Source: https://context7.com/pashagolub/pgxmock/llms.txt Expect an `Exec()` call for INSERT, UPDATE, DELETE, or other non-query SQL statements. Use `WithArgs()` to specify expected arguments and `WillReturnResult()` to define the outcome. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestExec(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect INSERT with arguments and return affected rows mock.ExpectExec("INSERT INTO users"). WithArgs("john", "john@example.com"). WillReturnResult(pgxmock.NewResult("INSERT", 1)) // Execute the INSERT result, err := mock.Exec(context.Background(), "INSERT INTO users (name, email) VALUES ($1, $2)", "john", "john@example.com") if err != nil { t.Fatal(err) } // result.RowsAffected() == 1 if result.RowsAffected() != 1 { t.Errorf("expected 1 row affected, got %d", result.RowsAffected()) } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect CopyFrom Operation Source: https://context7.com/pashagolub/pgxmock/llms.txt Use ExpectCopyFrom to mock a pgx.CopyFrom operation. It returns the number of rows affected. ```go package main import ( "context" "testing" "github.com/jackc/pgx/v5" "github.com/pashagolub/pgxmock/v5" ) func TestCopyFrom(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect COPY operation mock.ExpectCopyFrom( pgx.Identifier{"public", "users"}, []string{"id", "name", "email"}, ).WillReturnResult(3) // Prepare data source rows := [][]interface{}{ {1, "Alice", "alice@example.com"}, {2, "Bob", "bob@example.com"}, {3, "Charlie", "charlie@example.com"}, } // Execute COPY count, err := mock.CopyFrom( context.Background(), pgx.Identifier{"public", "users"}, []string{"id", "name", "email"}, pgx.CopyFromRows(rows), ) if err != nil { t.Fatal(err) } // count == 3 if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Successful pgxmock Test Case Source: https://github.com/pashagolub/pgxmock/blob/master/README.md This test uses pgxmock to verify that the recordStats function correctly updates product views and inserts into product_viewers within a transaction. It asserts that all expectations are met upon successful execution. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) // a successful case func TestShouldUpdateStats(t *testing.T) { mock, err := pgxmock.NewPool() if err != nil { t.Fatal(err) } defer mock.Close() mock.ExpectBegin() mock.ExpectExec("UPDATE products"). WillReturnResult(pgxmock.NewResult("UPDATE", 1)) mock.ExpectExec("INSERT INTO product_viewers"). WithArgs(2, 3). WillReturnResult(pgxmock.NewResult("INSERT", 1)) mock.ExpectCommit() // now we execute our method if err = recordStats(mock, 2, 3); err != nil { t.Errorf("error was not expected while updating: %s", err) } // we make sure that all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Expect Ping to Fail in Go Source: https://context7.com/pashagolub/pgxmock/llms.txt Use `mock.ExpectPing().WillReturnError()` to mock a failing `Ping()` call. This allows testing how your application handles connection errors during health checks. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestPingError(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect ping to fail mock.ExpectPing().WillReturnError(fmt.Errorf("connection refused")) err := mock.Ping(context.Background()) // err.Error() == "connection refused" if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Disable Ordered Expectations in pgxmock Source: https://context7.com/pashagolub/pgxmock/llms.txt Use MatchExpectationsInOrder(false) to allow expectations to be met in any order, useful for parallel operations. Ensure all expectations are met using ExpectationsWereMet(). ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestUnorderedExpectations(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Disable ordered matching for parallel operations mock.MatchExpectationsInOrder(false) mock.ExpectExec("INSERT INTO table_a"). WillReturnResult(pgxmock.NewResult("INSERT", 1)) mock.ExpectExec("INSERT INTO table_b"). WillReturnResult(pgxmock.NewResult("INSERT", 1)) // Execute in reverse order - still passes mock.Exec(context.Background(), "INSERT INTO table_b (col) VALUES (1)") mock.Exec(context.Background(), "INSERT INTO table_a (col) VALUES (2)") if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Optional Expectation with Maybe Source: https://context7.com/pashagolub/pgxmock/llms.txt Use the Maybe() modifier to make an expectation optional. If the mocked operation is not called, it will not cause a test failure. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestMaybeExpectation(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Optional ping - won't fail if not called mock.ExpectPing().Maybe() // Required query mock.ExpectQuery("SELECT 1"). WillReturnRows(mock.NewRows([]string{"one"}).AddRow(1)) // Only execute the query, skip ping mock.Query(context.Background(), "SELECT 1") // Still passes even though Ping wasn't called if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Failing pgxmock Test Case with Rollback Source: https://github.com/pashagolub/pgxmock/blob/master/README.md This test verifies that the recordStats function correctly handles errors during database operations by rolling back the transaction. It sets up an expectation for an error during the INSERT statement and asserts that an error is returned. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) // a failing test case func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) { mock, err := pgxmock.NewPool() if err != nil { t.Fatal(err) } defer mock.Close() mock.ExpectBegin() mock.ExpectExec("UPDATE products"). WillReturnResult(pgxmock.NewResult("UPDATE", 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(mock, 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) } } ``` -------------------------------- ### Expectation Count with Times Source: https://context7.com/pashagolub/pgxmock/llms.txt Use the Times(n) modifier to specify that an expectation must be fulfilled exactly n times. If called fewer or more times, the test will fail. ```go package main import ( "context" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestTimesExpectation(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) // Expect ping to be called exactly 3 times mock.ExpectPing().Times(3) // Call ping 3 times mock.Ping(context.Background()) mock.Ping(context.Background()) mock.Ping(context.Background()) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` -------------------------------- ### Simulate Row Error in pgxmock Source: https://context7.com/pashagolub/pgxmock/llms.txt Use RowError(rowIndex, error) on a pgxmock.Rows object to simulate an error during row processing. This error will be returned when scanning the specified row. ```go package main import ( "context" "fmt" "testing" "github.com/pashagolub/pgxmock/v5" ) func TestRowError(t *testing.T) { mock, _ := pgxmock.NewConn() defer mock.Close(context.Background()) rows := mock.NewRows([]string{"id", "name"}). AddRow(1, "Alice"). AddRow(2, "Bob"). RowError(1, fmt.Errorf("data corruption detected")). // Error on second row AddRow(3, "Charlie") mock.ExpectQuery("SELECT").WillReturnRows(rows) result, _ := mock.Query(context.Background(), "SELECT id, name FROM users") defer result.Close() count := 0 for result.Next() { var id int var name string if err := result.Scan(&id, &name); err != nil { // Error occurs when scanning row 2 t.Logf("Row %d error: %v", count, err) } count++ } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.