On Tue, Sep 07, 2010 at 05:29:44PM +0100, Mark Morgan wrote: > Heya folks, > > I'm looking to write DBD::Mock (proposed name) that can be used for
There's already a DBD::Mock http://search.cpan.org/perldoc?DBD::Mock > transparent mocking of other DBDs for purposes of integration tests, and am > looking for comments on my proposal. I've done some investigation in what > would be involved with this, but having people who are more familiar with > DBI development would definitely help to determine if I'm on the right > track, and whether it would be worthwhile. > > The situation that I've run into with a number of large systems is that it's > very difficult to have repeatable end-to-end integration tests, usually > because of db complexity. When doing integration tests, it may not be > feasible to have full fixture data for the db, as that becomes very > difficult to maintain. I'm looking at turning this problem around, so that > integration tests can be run in one of two modes, record or playback. Ok. > In record mode, DBI_AUTOPROXY would be used to shunt the requests to the > mock DBD. That would dispatch the request to the requested DBD, but also > log the request and response, saving both to a local file. In playback > mode, DBI_AUTOPROXY would still be needed, but in this case it would > intercept the requests, and return the saved response (assuming the request > is the expected one). Nothing would be passed through the requested DBD, > instead being handled by the mock DBD and it's recorded request data. Tests > would normally be run in playback mode; recording would only be required > when changes in the code or the tests result in DBI request profile being > modified. To operate without any mocking at all, it's just a simple case of > not specifying the DBI_AUTOPROXY, and then things will go through as normal > to the requested DBD. So effectively it's acting as a cache, but for non-select statements in addition to select statements. > From an initial prototype implementation, the core code is somewhat similar > to DBD::Proxy (indeed, I used that as a reference implementation for the > prototype). That module could conceivably be used as a mechanism for > implementation, but that would add quite a bit of complexity to the test > setup to do so (for configuring the proxy destination and such) that I > believe a separate specialised DBD would be a better approach. I'd *very* *strongly* recommend you consider DBD::Gofer. It has (almost) everything you need already in place. See: http://www.slideshare.net/Tim.Bunce/dbdgofer-200809 and http://timbunce.blip.tv/file/3693768/ > Can anyone see any issues with the approach above? I believe it is sound, > but there may be gotcha's I'm unaware of, or a better way to implement this > functionality that would be as transparent to test writers. Implementing the kind of recording and playback you're considering would be almost trivial with Gofer. Just implement a custom Gofer transport, which is easy. In fact I almost implemented this myself some time ago for similar needs. There's already support for client-side caching that's similar to what you want, but only works for select statements. (One possible only snag is that Gofer doesn't currently support transactions but that's relatively easy to fix to the extent that you need for this.) Assuming you go with this approach (did I mention it was highly recommended :) then your logic would live in a Gofer transport class like DBI::Gofer::Transport::TotalCache. You'd select it using something like: DBI_AUTOPROXY="dbi:Gofer:transport=TotalCache;file=foo;mode=record" Tim.