sbatson5/firestore-jest-mock

Internally assert that required parameters are provided in the right order

Opened this issue · 1 comments

Summary

While it is useful for users to be able to assert that specific functions are called with the parameters they expect, it may be useful for firestore-jest-mock to make its own assertions that ensure consistency with Firestore's API. For example, the transaction mock doesn't assert that read options, if provided, are the last argument of Transaction's variadic getAll method. It would be easy to accidentally pass that object first, followed by the document refs to get. A nice error message or a warning in the console (somehow) would suit better here than a TypeError when we try to call our mocked DocumentReference methods on the wrong type of object.

Motivation

This sort of check would enforce internal consistency as well as user sanity. We would catch bugs caused by incorrect API calls before the user boots up a Firestore emulator or deploys their product!

Potential Hills

Maintenance would be a problem. If Firestore's API suddenly changes to be more permissive with certain calls (unlikely in the case of variadic methods, but still a possibility) then we would need to update quickly to follow suit. This is why a logged warning may be in order. I don't know how to expose those properly to Jest other than regular console logs (which are invisible in --silent runs), so we may need to think up some solution for that too.

Alternative Directions

Semantic Assertions

We may instead create some way for users to assert the semantics of certain calls. For example, users can already assert that a Transaction object was called upon to update a ref at a specific path since our mock ref gets passed directly to Transaction.update. All one must do is expect that mockTransactionUpdate was called where the first argument includes the path key and a given database path. My company's own projects have already adopted a custom matcher, toHaveFirestorePath, for that very purpose, which may be useful enough to add here in a PR. If we can expand this sort of semantic assertion into more areas, such as direct modifications to Firestore refs (ref.update, for example), which cannot be asserted in this same manner, then users of firestore-jest-mock would be able to replace the current idea of "This is how we interact with Firestore" with "This is how Firestore interprets my instructions." This way, any loss in semantic meaning when test Firestore interactions is caught and tested correctly, even more maintainably.

Updated for clarity. Also added a ditty about a potential alternative direction: semantic assertions.