dmurvihill / firebase-mock

Firebase mock library for writing unit tests
55 stars 20 forks source link

Erratic behavior on interacting with subcollections #59

Open lesmo opened 4 years ago

lesmo commented 4 years ago

Hi,

Thanks for keeping up with firebase-mock!

So I've started to do some testing with firebase-mock with facebook/jest but I'm starting to face a strange problem. When running my tests, sometimes they'll succeed and sometimes they won't if I decide to run some setup inside beforeEach and afterEach: image

Without changes, running the same tests: image

I'm not sure if this is some sort of race condition, given that jest parallelizes testing to reduce time. To avoid collisions or unpredictable behavior during my tests (precisely because of that) I generate random IDs before creating new documents for my setup and then use those IDs for testing my REST API. Using --runInBand flag in jest didn't change the outcome though.

I would assume that multiple calls to .set, .delete, .create, and all of those won't affect firebase-mock internals (apart from the data)... but apparently, somehow it does? As you can see in the screenshots, on subsequent tests, for some reason, .set (and further down .delete) does not exist because .doc() is not working as expected for subcollections?

See the code ```ts let EVENT_ID: string; let GIVEAWAY_ID: string; let PARTICIPANT_ID: string; beforeEach(async () => { EVENT_ID = cuid(); GIVEAWAY_ID = cuid(); PARTICIPANT_ID = getGiveawayParticipantId(GIVEAWAY_ID, 'user1'); await firestore .collection('events') .doc(EVENT_ID) .set({ address: 'Address', coordinates: new f.GeoPoint(0, 0), title: `${EVENT_ID} Event`, subtitle: `Subtitle`, images: { compact: 'https://via.placeholder.com/350x150', cover: 'https://via.placeholder.com/350x350' }, startDate: f.Timestamp.fromDate(moment('20200101').toDate()), }); await firestore .collection('events') .doc(EVENT_ID) .collection('giveawayParticipants') .doc(PARTICIPANT_ID) // this is where it breaks for some calls .set({ userId: 'user1', giveawayId: GIVEAWAY_ID, entryDate: f.Timestamp.fromDate(moment('20200101T01').toDate()) }); }); afterEach(async () => { await firestore .collection('events') .doc(EVENT_ID) .delete(); await firestore .collection('events') .doc(EVENT_ID) .collection('giveawayParticipants') .doc(PARTICIPANT_ID) // this is where it breaks for some calls .delete(); }); ```

The same strategy works for other tests properly, it's precisely with subcollections where I'm faced with this "sometimes not working" behavior. The issue even occurs within my REST API code (which is mocked with firestore-mock), so it's definitely a thing inside firestore-mock.

See the code ```ts const batch = this.firebaseService.firestore.batch(); batch.create( this.firebaseService.firestore .collection('events') .doc(this.eventId) .collection('giveawayParticipants') .doc(participantId), participantData ); // ... some other stuff in the batch try { await batch.commit(); } catch (err) { // This generates the screenshot's response throw new Errors.UnprocessableEntityError(err.message); } ```

This is what I was expecting, but this was literally a struck of luck, after running jest around 3 to 5 times: image

I'm currently using firebase-mock from master (npm i -s github:dmurvihill/firebase-mock#master).