Skip to content

Testing Strategy

LAP-CHRIS\chris edited this page Mar 10, 2026 · 1 revision

Language: English | Português (Brasil)

Testing Strategy

DbSqlLikeMem works best as the fast SQL-focused layer in your test strategy. It gives you realistic-enough SQL behavior for developer feedback, while a smaller set of real-provider tests still protects release-critical paths.

Where it fits best

Pure unit tests

Use plain unit tests when the scenario does not need SQL at all.

SQL-focused repository and service tests

Use DbSqlLikeMem when the scenario depends on SQL shape, seeded rows, transactions, savepoints, or provider-aware parsing, but does not need a running database server.

Real-provider integration tests

Keep a smaller suite against the real provider for engine-specific behavior, migration validation, production execution plans, and infrastructure-sensitive cases.

Recommended test layers

  • Keep most day-to-day repository and service tests on DbSqlLikeMem for fast feedback.
  • Add targeted provider-sensitive tests for dialect branches such as RETURNING, OUTPUT, temporary tables, or provider-specific transaction behavior.
  • Keep end-to-end and release-gate scenarios on the real database engine.

Good suite structure

1. Start with compact scenario tests

Use DbMockConnectionFactory.Create*WithTables(...) when you want a short setup inside the test body.

var (db, connection) = DbMockConnectionFactory.CreateSqliteWithTables(
    d => d.AddTable("Users",
        [new Col("Id", DataTypeDef.Int32()), new Col("Name", DataTypeDef.String())],
        [new Dictionary<int, object?> { [0] = 1, [1] = "Ana" }]));

connection.Open();

2. Move repeated structures into fixtures

When many tests share the same schema, promote that setup into a fixture or use schema snapshots so each test can start from a known structure with less boilerplate.

3. Reset volatile state instead of rebuilding everything

Use db.ResetVolatileData() when you want to keep table definitions but clear rows and reset identity state. Use connection.ResetAllVolatileData() when you also need to clear connection-scoped temporary state and invalidate savepoints.

4. Add interception only where it adds value

Use interception for recording, logging, tracing, or resilience simulation. Keep the default test path simple unless the scenario needs extra observability.

Picking the right API surface

  • Use raw ADO.NET when you want maximum control over commands, readers, and transactions.
  • Use Dapper when your production code already uses Dapper or when you want concise data access tests.
  • Use the ORM and ecosystem packages when your application creates connections through EF Core, LinqToDB, or other higher-level adapters.

Common strategy mistakes

  • Treating mock execution metrics as production performance benchmarks.
  • Skipping provider selection and assuming SQL is identical across dialects.
  • Rebuilding complex schemas in every test instead of using fixtures or snapshots.
  • Replacing all real-provider tests instead of keeping a smaller final verification layer.

A practical default

A good default is:

  • write most SQL-facing repository tests with DbSqlLikeMem,
  • keep provider-specific scenarios near the corresponding provider page,
  • add interception only for diagnostics or resilience cases,
  • keep a smaller real-database suite for final confidence.

Related pages

Start in English

English

English Guided Walkthroughs

English Advanced Guides

English Providers

English Ecosystem

Português (Brasil)

Walkthroughs Guiados em Português

Guias Avançados em Português

Provedores em Português

Ecossistema em Português

Clone this wiki locally