DATA-DOG/go-sqlmock
Sql mock driver for golang to test database interactions
Stale — last commit 2y ago
weakest axisnon-standard license (Other); last commit was 2y ago…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓28+ active contributors
- ✓Distributed ownership (top contributor 26% of recent commits)
- ✓Other licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ⚠Stale — last commit 2y ago
- ⚠Non-standard license (Other) — review terms
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/data-dog/go-sqlmock)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/data-dog/go-sqlmock on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: DATA-DOG/go-sqlmock
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/DATA-DOG/go-sqlmock shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 28+ active contributors
- Distributed ownership (top contributor 26% of recent commits)
- Other licensed
- CI configured
- ⚠ Stale — last commit 2y ago
- ⚠ Non-standard license (Other) — review terms
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live DATA-DOG/go-sqlmock
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/DATA-DOG/go-sqlmock.
What it runs against: a local clone of DATA-DOG/go-sqlmock — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in DATA-DOG/go-sqlmock | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 633 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of DATA-DOG/go-sqlmock. If you don't
# have one yet, run these first:
#
# git clone https://github.com/DATA-DOG/go-sqlmock.git
# cd go-sqlmock
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of DATA-DOG/go-sqlmock and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "DATA-DOG/go-sqlmock(\\.git)?\\b" \\
&& ok "origin remote is DATA-DOG/go-sqlmock" \\
|| miss "origin remote is not DATA-DOG/go-sqlmock (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "sqlmock.go" \\
&& ok "sqlmock.go" \\
|| miss "missing critical file: sqlmock.go"
test -f "driver.go" \\
&& ok "driver.go" \\
|| miss "missing critical file: driver.go"
test -f "expectations.go" \\
&& ok "expectations.go" \\
|| miss "missing critical file: expectations.go"
test -f "rows.go" \\
&& ok "rows.go" \\
|| miss "missing critical file: rows.go"
test -f "statement.go" \\
&& ok "statement.go" \\
|| miss "missing critical file: statement.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 633 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~603d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/DATA-DOG/go-sqlmock"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
go-sqlmock is a mock SQL driver for Go that implements the database/sql/driver interface without requiring a real database connection. It allows developers to simulate any SQL driver behavior in unit tests by setting up strict expectations for queries, prepared statements, and result sets, enabling proper TDD workflows for database-dependent code. Single-package monolith structure: core driver logic in driver.go, rows.go, statement.go, and query.go; expectations system in expectations.go with version-specific variants; utility types in argument.go, column.go, and result.go. Examples subdirectory contains three complete test suites (basic/, blog/, orders/) demonstrating different patterns. Version-specific code branching (e.g., sqlmock_before_go18.go vs sqlmock_go18.go) handles API changes across Go releases.
👥Who it's for
Go backend developers writing unit tests for database-interacting code who want to avoid test dependencies on real database instances. Database library maintainers and engineers building database abstraction layers also use it to verify driver behavior without external services.
🌱Maturity & risk
Highly mature and stable: the README explicitly states 'this library is now complete and stable' with no new feature activity expected. It has comprehensive test coverage (expectations_*_test.go, rows_test.go, statement_test.go, etc.), CI via Travis CI (.travis.yml), and supports Go 1.8 through 1.19+ (evidenced by version-specific files like sqlmock_go18.go, sqlmock_go19.go). However, the maintainer is actively seeking new maintainers (see #230 in README), indicating potential future maintenance risk.
Low technical risk but significant maintenance risk: the library has zero third-party dependencies (only internal go.mod with kisielk/sqlstruct), making it stable. However, it's a single-maintainer project seeking handoff, and lacks recent commit activity in the visible data. The repository structure shows version-specific implementations (expectations_before_go18.go, rows_go18.go, sqlmock_go19.go) that will accumulate technical debt as Go versions evolve, requiring active maintenance.
Active areas of work
The project is in maintenance mode. No active feature development is visible; instead, the maintainer is seeking new ownership (issue #230 mentioned in README). The file structure shows support for Go 1.8 through 1.19+, but no evidence of recent version migrations beyond 1.19 in the current file list.
🚀Get running
git clone https://github.com/DATA-DOG/go-sqlmock.git && cd go-sqlmock && go mod download && go test ./...
Daily commands: Run tests with: go test ./... or go test -v ./... for verbose output. Run individual example suites: cd examples/blog && go test ./... or cd examples/orders && go test ./...
🗺️Map of the codebase
sqlmock.go— Main entry point exposing New() and NewWithDSN() functions; every user of this library starts here to create mock database instances.driver.go— Implements sql/driver.Driver interface and manages the core mock driver registration; foundational for all SQL mocking.expectations.go— Defines the Expectations interface and ExpectedQuery/ExpectedExec structs that form the contract for what queries should happen and in what order.rows.go— Implements sql/driver.Rows interface to return mocked result sets; critical for SELECT query response behavior.statement.go— Implements sql/driver.Stmt interface for prepared statements; bridges user code to mocked query execution.query.go— Handles query matching logic and argument validation; ensures strict expectation ordering and accurate error reporting.argument.go— Defines Argument interface and concrete implementations for matching/validating SQL arguments; critical for test assertion accuracy.
🧩Components & responsibilities
- Driver (driver.go, sqlmock_goXY.go) (sql/driver.Driver interface, sync.Mutex for connection pool thread-safety) — Implements sql/driver.Driver; creates and manages mock connections; routes Open() and Close() calls.
- Failure mode: If driver registration fails or Open() returns an error, database/sql cannot use the mock and tests fail immediately.
- Expectations (expectations. — undefined
🛠️How to make changes
Add a new custom Argument matcher
- Define a new type implementing the Argument interface in argument.go with Match() and String() methods (
argument.go) - Add a public constructor function (e.g., MyCustomArg()) following the pattern of NamedArg or EqualToTime (
argument.go) - Write unit tests in argument_test.go covering success and failure cases (
argument_test.go) - Document the matcher in a new example file under examples/ showing when to use it (
examples/basic/basic_test.go)
Support a new Go version with driver features
- Create new files sqlmock_goXY.go and statement_goXY.go with version-specific implementations (
sqlmock_go19.go) - Update expectations_goXY.go if Context or parameter handling changes are needed (
expectations_go18.go) - Create corresponding _test.go files for Go version-specific test cases (
sqlmock_go19_test.go) - Update .travis.yml to test the new Go version in CI (
.travis.yml)
Add new expectation validation rules
- Define validation logic in expectations.go or expectations_goXY.go depending on Go version requirements (
expectations.go) - Implement matching logic in query.go's QueryMatcher method or equivalent (
query.go) - Add unit tests covering valid, invalid, and edge cases in expectations_test.go (
expectations_test.go) - Document the new validation rule in README.md with code examples (
README.md)
🔧Why these technologies
- Go 1.15+ with database/sql/driver interfaces — Standard library SQL driver interface is the contract that sqlmock implements; enables drop-in replacement for real database drivers without modifying application code.
- Interface-based design (Argument, Expectations, Rows) — Allows flexible extension of matchers and assertions; users can implement custom argument validators without forking the library.
- Strict expectation ordering (default) — Catches ordering bugs in application code early; prevents flaky tests from accidental query reordering.
- Version-specific code paths (sqlmock_goXY.go) — Context support (Go 1.8+), named parameters, and driver enhancements vary by Go version; separate files keep compatibility clean without preprocessor directives.
⚖️Trade-offs already made
-
Strict expectation ordering is the default behavior
- Why: Enforces deterministic test execution and makes query sequences explicit, improving test quality.
- Consequence: Tests that intentionally allow flexible query order must explicitly disable strict mode with NewMockDB(WithoutExpectedExecOrder()); adds friction for non-deterministic tests.
-
No real database connection required
- Why: Enables fast, isolated unit tests without infrastructure dependencies and avoids test flakiness from DB state.
- Consequence: Tests cannot catch database schema mismatches, SQL syntax errors on actual DB, or concurrency deadlocks that only appear under real DB conditions.
-
Separate code paths for each Go version
- Why: Cleanly supports Context (1.8+), named parameters (1.8+), and driver features added over time without runtime checks.
- Consequence: Maintenance burden increases with new Go versions; must add new version files and update import logic for each release.
-
Rows and Columns are mocked in-memory
- Why: Avoids network I/O and enables deterministic column type handling in tests.
- Consequence: Cannot test edge cases tied to actual database driver behavior (e.g., type conversions, streaming very large result sets).
🚫Non-goals (don't propose these)
- Does not provide a real database server or storage layer; purely in-memory mock.
- Does not validate SQL syntax or semantics; passes through arbitrary SQL strings without parsing.
- Does not support transaction isolation or ACID semantics; mocks are single-threaded per connection by default.
- Does not replicate actual database driver performance characteristics or resource limits.
- Does not provide query optimization or explain plan simulation.
- Does not handle database-specific features (stored procedures, triggers, views) beyond basic query/exec.
- Does not persist mock state across multiple sqlmock.New() instantiations; each mock is independent.
🪤Traps & gotchas
Version-specific code paths: files like sqlmock_before_go18.go vs sqlmock_go18.go vs sqlmock_go19.go are conditionally compiled using Go build tags or file naming conventions—tests must be run against target Go versions to validate. Strict expectation ordering by default: queries must match registered expectations in exact order unless WithoutExpectationsOrder() is set, causing confusing test failures if order mismatches. Named parameters and Context features only available in Go 1.8+; tests using exec.Context will fail silently on Go 1.7 or earlier due to conditional compilation.
🏗️Architecture
💡Concepts to learn
- SQL Driver Interface (database/sql/driver) — This repo is an entire implementation of Go's sql/driver interface—understanding Driver, Conn, Stmt, and Rows interfaces is essential to understanding how sqlmock mocks database behavior
- Expectation-Driven Testing / Mock Order Verification — sqlmock's core feature is strict expectation order matching—mocks validate that your code executes queries in the exact sequence you defined, catching logic bugs early
- Test-Driven Development (TDD) — The README explicitly positions sqlmock as enabling TDD workflows by allowing test-first database code without external DB setup
- Prepared Statements & Parameter Binding — sqlmock mocks prepared statement execution and parameter validation—critical for testing SQL injection safety and parameter handling in your code
- Conditional Compilation / Build Tags — The codebase uses Go version-specific files (sqlmock_go18.go, sqlmock_go19.go) to support different API versions across Go releases—understanding this pattern is essential for maintaining compatibility
- Context Handling in Database Operations — Go 1.8+ added context.Context support to database operations; sqlmock conditionally supports this with version-gated implementations (ExecContext, QueryContext)
- Named Parameters in SQL — Some databases support named parameters (:param syntax); sqlmock mocks this feature for Go 1.8+ to allow testing code that uses database-specific SQL extensions
🔗Related repos
DATA-DOG/go-txdb— Companion library by same org for functional testing with real database transactions; recommended in README as alternative to sqlmock for integration testsgo-sql-driver/mysql— Real MySQL driver for Go; README uses this as the reference example of code that sqlmock helps testlib/pq— PostgreSQL driver for Go; common database driver used with sqlmock in production codebasesgolang/mock— Official Go mock code generator; can be used alongside sqlmock for broader service mocking beyond database layertestify/suite— Popular testing framework used with sqlmock in examples for organizing test fixtures and assertion helpers
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Actions CI/CD workflow to replace deprecated Travis CI
The repo uses .travis.yml which is referenced in the README badges. Travis CI has undergone significant changes and many projects have migrated to GitHub Actions. This would modernize the CI pipeline, provide faster feedback, and improve visibility within the GitHub UI. The repo targets go1.15+ with version-specific test files (rows_go13_test.go, expectations_go18.go, etc.), so the workflow should test multiple Go versions.
- [ ] Create .github/workflows/test.yml with matrix testing for Go 1.15, 1.18, 1.19, 1.20, and latest stable
- [ ] Include test coverage reporting integration with codecov.io (already referenced in README)
- [ ] Add linting steps using golangci-lint for code quality checks
- [ ] Update README.md to replace Travis CI badge with GitHub Actions badge
- [ ] Verify all existing tests pass: argument_test.go, driver_test.go, expectations_test.go, rows_test.go, statement_test.go, etc.
Add comprehensive integration tests for Go 1.19+ Context cancellation features
The codebase has version-specific files for Go 1.8, 1.13, 1.18, and 1.19+ (sqlmock_go19.go, sqlmock_go19_test.go), indicating context-dependent behavior. However, sqlmock_go19_test.go likely has limited coverage. The README mentions 'supports go1.8 Context related featu[res]' (text cut off), suggesting context support is a key feature. New contributors could expand test coverage for context cancellation, deadlines, and timeouts across different Go versions.
- [ ] Review sqlmock_go19_test.go and sqlmock_go19.go to identify context behavior gaps
- [ ] Add tests for context.WithCancel() scenarios in statement execution
- [ ] Add tests for context.WithTimeout() and context.WithDeadline() in query/exec operations
- [ ] Test concurrent context cancellation across multiple connections (mentioned as supported)
- [ ] Add tests to expectations_go19_test.go for context-aware expectation validation
- [ ] Ensure backward compatibility with Go 1.15 baseline
Extract and refactor version-specific code into a compatibility layer package
The repo has significant version-specific code split across multiple files: sqlmock_before_go18.go, sqlmock_go18.go, sqlmock_go18_19.go, sqlmock_go19.go, statement_before_go18.go, statement_go18.go, and similar for expectations and rows. This creates maintenance burden and makes it harder to follow the core logic. Extracting these into an internal compatibility package (e.g., internal/compat) would improve readability and reduce duplication.
- [ ] Create internal/compat/context.go for context handling differences across Go versions
- [ ] Create internal/compat/rows.go for ColumnTypeScanType and NamedValueChecker differences
- [ ] Create internal/compat/statement.go for ExecContext/QueryContext patterns
- [ ] Refactor sqlmock.go, driver.go, statement.go to use the new compat package
- [ ] Consolidate expectations_before_go18.go and expectations_go18.go logic using compat helpers
- [ ] Ensure all existing tests pass: run full test suite against Go 1.15, 1.18, 1.19+
- [ ] Update internal documentation in files to explain version-specific behavior
🌿Good first issues
- Add missing test coverage for column.go—the file has no corresponding column_test.go with comprehensive edge cases for column type conversion and NULL handling
- Document version-specific behavior differences in README: create a compatibility matrix table showing which features (Context support, Named params, concurrent connections) are available in Go 1.8, 1.13, 1.18, 1.19+
- Refactor version-specific code: consolidate duplicated logic in sqlmock_before_go18.go, sqlmock_go18.go, sqlmock_go18_19.go, and sqlmock_go19.go into shared code with interface adapters to reduce maintenance burden
⭐Top contributors
Click to expand
Top contributors
- @l3pp4rd — 26 commits
- [@Nikita Koryabkin](https://github.com/Nikita Koryabkin) — 15 commits
- @ninadingole — 6 commits
- @IvoGoman — 6 commits
- @asahasrabuddhe — 5 commits
📝Recent commits
Click to expand
Recent commits
63e2ff0— Merge pull request #340 from DATA-DOG/feature/316 (ninadingole)49e34f6— Merge pull request #314 from chrisirhc/patch-1 (ninadingole)4a27a75— Add WithTXOption expectation to ExpectBegin (ninadingole)f3575cd— add missing closing curly brace (ninadingole)52e994a— Merge branch 'master' into patch-1 (ninadingole)645bbfb— Add test for WillReturnRows function returns Nil (ninadingole)6bed17c— Merge pull request #307 from Woody1193/master (diegommm)6622224— Merge pull request #333 from sfc-gh-tvidyasankar/patch-1 (l3pp4rd)f53e637— adding a test case to support empty expectedSQL check (sfc-gh-tvidyasankar)faba995— Update query.go (sfc-gh-tvidyasankar)
🔒Security observations
The go-sqlmock codebase is a testing utility library with relatively low attack surface since it operates on mock database connections. No critical vulnerabilities were identified. However, the project has moderate security concerns: outdated Go version requirement (1.15) and an outdated external dependency (sqlstruct) that should be updated. The codebase appears well-maintained with no obvious injection vulnerabilities, hardcoded secrets, or infrastructure misconfigurations visible in the provided structure. The project's stability and focus on testing utilities further reduce risk exposure. Primary recommendations are updating the Go version requirement and dependency versions to benefit from security patches.
- Medium · Outdated Go Version Requirement —
go.mod. The project specifies 'go 1.15' in go.mod, which is significantly outdated (released in August 2020). This version is no longer supported and may contain known security vulnerabilities in the Go runtime itself. Fix: Update the minimum Go version requirement to a currently supported version (1.21 or later). This ensures users benefit from security patches and improvements in the Go runtime. - Medium · Outdated Dependency —
go.mod. The dependency 'github.com/kisielk/sqlstruct' is pinned to version '0.0.0-20201105191214-5f3e10d3ab46' (November 2020), which is over 3 years old. This dependency may contain unpatched security vulnerabilities. Fix: Review and update the sqlstruct dependency to the latest available version. Run 'go get -u github.com/kisielk/sqlstruct' and verify compatibility with the codebase. - Low · No go.sum Verification —
go.sum. While a go.sum file is present (indicated in the file listing), without viewing its contents, it cannot be verified that dependency integrity checks are properly maintained. Fix: Ensure go.sum is committed to version control and regularly validated. Use 'go mod verify' to ensure dependency integrity. - Low · Travis CI Configuration May Be Outdated —
.travis.yml. The project uses .travis.yml for CI/CD. Travis CI has deprecated its open-source offering for public repositories in favor of GitHub Actions. The configuration may not be actively maintained. Fix: Consider migrating to GitHub Actions for CI/CD pipeline management, which is better integrated with GitHub and more actively maintained for public repositories.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.