I am looking for some advice about structuring Delphi programs for maintainability. I've come to Delphi programming after a couple of decades of mostly C/C++ though I first learned to program with Turbo Pascal, so I'm not uncomfortable with the basic language. In my previous experience with C++ and C#, I became a TDD convert through using cxxtest and NUnit.
I have inherited this program that I am now responsible for maintaining. It consists mainly of forms, and a couple of data modules. The application business logic and data access is mainly scattered about the forms, and the data modules are mostly just places for global ADO objects to live. The database access is generally done by referring to a global instance of TADOQuery or TADOCommand, formatting SQL text right into the relevant property of the object, and calling its Open or Execute method.
I am trying to get the business logic into a degree of encapsulation where it can be unit-tested. I've seen this answer and it makes perfect sense as far as abstracting logic from forms. I am wondering what the best practices are for data access. My thinking is that the data modules should expose a sort of app-specific mini-API (probably with all virtual methods) so that they can be replaced with mock objects for testing. The link at this other answer shows some examples that lead me to believe I'm on the right track, but I'm still interested in seeing some kind of best practices document about data modules. Most of the pages that I can find through Google present the same kind of examples about all the cool stuff you can do at design time with hooking up data-bound controls to queries and that sort of thing, which I'm not very interested in at the moment.