Search code examples
tddpersistenceabstraction

TDD: how to test data persistence abstraction


problem statement

Let's say I want to implement a simple key-value storage, which provides basic CRUD operations. The only requirement is that all the modifications should persist between application launches. I'm not concerned about particular persistence mechanism, as it may change during development, or even be different depending on the platform.

the question

How should I approach testing such library / class / module (whichever it becomes in the end) ?

All the answers I found were focused on testing particular database solution, but that's what I want to avoid. I'm only concerned about the fact that changes are being persisted, not about how they're persisted.

Solutions I considered:

  • extract the actual persistence implementation, and test each implementation separately, and only test if the abstraction layer calls correct methods

The problem I see with this approach is large amount of code for very simple task, and the fact I'm still concerned about particular persistence mechanism in the end. This may complicate development, especially for such a simple thing as a key-value storage.

  • make some test that actually launches the application multiple times, and checks if the data changes are persisted between launches

That would test exactly what I need, but such a test would probably be expensive, and not necessarily easy to write.

  • Test only if the methods work for single process, do not test persistence at all

Well, the whole point of the library would be to test persistence. Say, some user settings, or game save. Testing if it works in memory doesn't test the real problem.

Maybe some other solution, I didn't think of?


I've read through most of the topics related to persistence and TDD here, and on other sites, but all I could find focuses on specific persistence mechanism.

somewhat related, but doesn't touch on the testing subject: How many levels of abstraction do I need in the data persistence layer?


Solution

  • A persistence layer is a port of your application. As such, your approach should be to write an adapter to that port, and test that adapter using an integration test.

    The test itself doesn't need to spin the adapter more than once - testing that things actually persist would be testing the persistence mechanism itself, and that's not your concern. At some point, you'll have to assume things work, and they have their own tests to make sure that's correct. A typical write and then read back test would do for most cases.

    Once the adapter exists, you can use several techniques for writing other tests - mock the adapter when it is a collaborator for other units, or use an in-memory implementation of the adapter (using a contract test to see that the in-memory implementation is the same as the other one).