google-cloud-go icon indicating copy to clipboard operation
google-cloud-go copied to clipboard

datastore: provide in-memory fakes

Open jbeder opened this issue 5 years ago • 4 comments

As the README notes, it's frowned-upon to overuse mocks. What I'd imagine most people want (at least, what I certainly want) is an in-memory fake instead. In particular, for the datastore client; I just want something that acts like datastore for my unit tests that's faster than spinning up the emulator.

This issue is for adding a fake implementation of dsiface.Client, but even better would be a way of creating a real *datastore.Client that talks to a fake in-memory server, so that prod code can just use *datastore.Client like you'd expect, and then test code can call dsfake.NewClient(...) to get an in-memory client to pass in.

I read the thread https://github.com/googleapis/google-cloud-go/issues/592, and it seems that the official answer is either (a) replay tools, or (b) these interfaces which you can use for mocking or faking. But both are more difficult for end-users: (a) requires hitting a real (or emulated) server, and then saving and rerunning tests, and (b) requires every user to implement a fake themselves. I suspect most people just want a drop-in fake that works like the real thing, just in-memory.

jbeder avatar Dec 29 '19 23:12 jbeder

See, e.g., here, which appears to be someone's attempt at writing a fake. As you can see, it's a partial implementation: good enough (presumably) for them, but not complete, so not really reusable by others. An officially supported one would be amazing.

jbeder avatar Dec 29 '19 23:12 jbeder

I may be missing something, but to me it sounds like the proposed reusable fake would have to have the same RPC semantics of the emulator in order for it to be complete and usable by the vast majority of users. Which to me then begs the question what is the main difference: in-process vs out-of-process? Is this a matter of the emulator being too slow to start and we want to ask for some startup optimization work on that?

BenWhitehead avatar Jan 09 '20 16:01 BenWhitehead

Yes, that's right, it's perhaps an issue of slowness, but the reason I phrased it like this is that the emulator starts up in a matter of a few seconds, whereas a good in-memory fake starts up in a matter of a few milliseconds (or even less than a millisecond). (The use case you should think about is that each file that touches a datastore will have ~10 unit tests, and each unit test might have ~10 test cases, so each file will start up and shut down a fake ~100 times.)

So it seemed to me that it wouldn't be feasible to take the existing emulator and make it that much faster to start up.

This suggests an alternative, though: a fast "reset" button on the datastore. It'd be OK for the emulator to start up in, say, a second, if each test case can reset it in a millisecond. It does make it more error-prone (you forget to reset it, leading to bugs; you don't know about the reset, leading to slow tests; test cases are no longer hermetic, so you can't run them in parallel).

jbeder avatar Jan 09 '20 18:01 jbeder

hey all, apologies on poking on this old thread and this is a long shot, but looking for a good in-memory fake for datastore (similar to bttest package). is anyone aware of a google-maintained/supported library?

david-argoff avatar Jun 30 '22 13:06 david-argoff

This is addressed by #6881 . We've decided to pursue a mocking strategy similar to what other packages (e.g. Firestore, Bigtable) use with an in-memory gRPC server.

telpirion avatar Oct 26 '22 18:10 telpirion