Skip to content

Add mock database infrastructure for unit testing persistence code #37

@bero

Description

@bero

Summary

Added mock database infrastructure to enable unit testing of database-dependent Bold code without requiring a real database connection.

Changes

New Files

UnitTest/Code/Mocks/BoldMockDatabase.pas

  • TBoldMockField - Mock implementation of IBoldField
  • TBoldMockParameter - Mock implementation of IBoldParameter
  • TBoldMockQuery - Mock implementation of IBoldQuery, IBoldExecQuery, IBoldDataSet, IBoldParameterized
  • TBoldMockDatabase - Mock implementation of IBoldDatabase with transaction tracking

UnitTest/Code/Mocks/Test.BoldMockDatabase.pas

  • 7 example unit tests demonstrating mock usage

Modified Files

UnitTest/UnitTest.dpr

  • Added references to new mock units

Usage Example

var
  MockDb: TBoldMockDatabase;
  Query: IBoldQuery;
begin
  MockDb := TBoldMockDatabase.Create;
  try
    // Configure mock data
    MockDb.MockQuery.SetFieldNames(['ID', 'Name', 'Value']);
    MockDb.MockQuery.AddRow([1, 'First', 100]);
    MockDb.MockQuery.AddRow([2, 'Second', 200]);

    // Use in tests
    Query := MockDb.GetQuery;
    Query.AssignSQLText('SELECT * FROM TestTable');
    Query.Open;
    
    Assert.AreEqual(2, Query.RecordCount);
    Assert.AreEqual(1, Query.FieldByName('ID').AsInteger);
    
    FMockDb.ReleaseQuery(Query);
  finally
    MockDb.Free;
  end;
end;

Technical Notes

Reference Counting

The mock classes disable Delphi's automatic interface reference counting by overriding _AddRef and _Release to return -1. This is because:

  • Field and parameter objects are cached and reused
  • Query and field lifetimes are managed by their parent objects
  • Without this, interface variables going out of scope would cause premature object destruction

Field Caching

TBoldMockQuery caches TBoldMockField objects in an internal list rather than creating new ones per call to FieldByName. Field values are updated from the current row when navigating (First, Next).

Test Results

  • 7 new mock database tests: All pass
  • Full test suite: 275 passed, 14 ignored, 0 failed

Future Work

  • Use mock infrastructure to test SQL generation code (BoldSqlNodes, BoldSqlQueryGenerator)
  • Use mocks to test persistence mappers (BoldPMappersDefault)
  • Create SQLite-based integration tests for full persistence cycle testing (files in UnitTest/Code/Integration/ are work-in-progress)

Labels

enhancement, testing

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions