* Don't try to interface between various SQLs. It's not the right place to make 'the cut'. Instead, interface via what the caller wants to achieve. It doesn't want to 'run an INSERT statement'. It wants to 'add a user'. So the interface should be Store<User> or something. Then it can just be backed by a hashmap in tests.
* The real power of DIP emerges in deep vertical stacks. Abstractions can point at abstractions all the way down (as long as they don't eventually point to IO). Which means you can unit test your real ReportController, it will hit your real ReportService, which will hit your real ReportStore (which will then hit a HashMap instead of a DB). No need to fake/lie at every layer down the stack like is done with typical unit testing. You get the all the upsides of Unit testing and Integration testing, with very few downsides.
mrkeen•16m ago
Couple of notes on the article:
* Don't try to interface between various SQLs. It's not the right place to make 'the cut'. Instead, interface via what the caller wants to achieve. It doesn't want to 'run an INSERT statement'. It wants to 'add a user'. So the interface should be Store<User> or something. Then it can just be backed by a hashmap in tests.
* The real power of DIP emerges in deep vertical stacks. Abstractions can point at abstractions all the way down (as long as they don't eventually point to IO). Which means you can unit test your real ReportController, it will hit your real ReportService, which will hit your real ReportStore (which will then hit a HashMap instead of a DB). No need to fake/lie at every layer down the stack like is done with typical unit testing. You get the all the upsides of Unit testing and Integration testing, with very few downsides.