I followed the Cloud Functions recommendation and created my unit testing in online mode, everything makes sense to me, but I am getting inconsistency when I am debugging. I just trying to reset the firestore state by resetting and seeding the database.
When I run my test suite separately, they work perfectly; if I run all the test suites together appear all the errors, I am pretty sure that this is related to the beforeEach hooks but idk how to fix them.
I have 3 test suites, I will share with you 1 of them and the function responsible of the reset of the firestore.
// eslint-disable-next-line spaced-comment
/// <reference types="jest" />
import { cleanup, getDb, initializeFirebase, makeChange, resetDb, wrap } from './util';
initializeFirebase();
import { streamerIsOffline, streamerIsOnline } from './__fixtures__/onStreamerUpdateSnaps';
import { getScheduler, SchedulerClientWrapper } from './../utils/SchedulerClientWrapper';
import onStreamerUpdate from '../onStreamerUpdate';
const db = getDb();
jest.mock('./../utils/SchedulerClientWrapper');
const mockedGetScheduler = jest.mocked(getScheduler, true);
const wrapped = wrap(onStreamerUpdate);
const schedulerClientWrapper = new SchedulerClientWrapper();
const mockedPause: jest.Mock = jest.fn();
const mockedResume: jest.Mock = jest.fn();
const mockedJobIsEnabled: jest.Mock = jest.fn();
schedulerClientWrapper.pause = mockedPause;
schedulerClientWrapper.resume = mockedResume;
schedulerClientWrapper.jobIsEnabled = mockedJobIsEnabled;
describe('onStreamerUpdate', () => {
beforeEach(
async () => {
await resetDb(); //I am resetting firestore here
mockedGetScheduler.mockClear();
jest.resetAllMocks();
});
it('should resume the scheduledJob when the first streamer becomes online',
async () => {
await updateStreamerStatus('64522496', true); //I am preparing the setup here
const beforeSnap = streamerIsOffline;
const afterSnap = streamerIsOnline;
const change = makeChange(beforeSnap, afterSnap);
mockedGetScheduler.mockReturnValue(schedulerClientWrapper);
mockedJobIsEnabled.mockResolvedValue(false);
await wrapped(change);
expect(mockedJobIsEnabled).toBeCalled();
expect(mockedResume).toBeCalled();
expect(mockedPause).not.toBeCalled();
});
afterAll(() => {
cleanup();
});
});
const updateStreamerStatus = async (streamerId: string, isOnline: boolean) => {
const stremersRef = db.collection('streamers');
const query = stremersRef.where('broadcasterId', '==', streamerId);
const querySnapshot = await query.get();
console.log('streamers', (await stremersRef.get()).docs.map((doc) => doc.data())); //I am debugging here
const streamerDocId = querySnapshot.docs[0].id;
await stremersRef.doc(streamerDocId).update({ isOnline });
};
And you can find the functions that wipe and seed firestore below:
import firebaseFunctionsTest from 'firebase-functions-test';
import { getApp, getApps, initializeApp, cert } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';
const projectId = 'latamqchallengetest';
export const { wrap, cleanup, firestore: firestoreTestData, makeChange } = firebaseFunctionsTest({
databaseURL: `https://${projectId}.firebaseio.com`,
storageBucket: `${projectId}.appspot.com`,
projectId: projectId,
}, './../google-credentials/latamqchallengetest-firebase-adminsdk.json');
export const initializeFirebase = () => {
if (getApps().length <= 0) {
initializeApp({
credential: cert('./../google-credentials/latamqchallengetest-firebase-adminsdk.json'),
});
}
return getApp();
};
export const getDb = () => {
initializeFirebase();
const db = getFirestore();
return db;
};
export const wipeDb = async () => {
const db = getDb();
const collections = await db.listCollections();
const deletePromises = collections.map((collectionRef) =>
db.recursiveDelete(collectionRef));
Promise.all([...deletePromises]);
};
export const seed = async () => {
const db = getDb();
await db.collection('streamers').add({
broadcasterId: '64522496',
broadcasterName: 'ITonyl',
color: '1565C0',
description: 'Sr. Truchita',
isOnline: false,
puuid: 'kRQyIDe5TfLhWtn8jXgo_4Zjlfg4rPypXWiPCXrkTMUsiQT3TYVCkVO6Au3QTdd4x-13CbluPA53dg',
summonerId: '9bnJOmLXDjX-sgPjn4ZN1_-f6m4Ojd2OWlNBzrdH0Xk2xw',
});
await db.collection('streamers').add({
broadcasterId: '176444069',
broadcasterName: 'Onokenn',
color: '424242',
description: 'El LVP Player',
isOnline: false,
puuid: 'Gbfj8FyB6OZewfXgAwvLGpkayA6xyevFfEW7UZdrzA6saKVTyntP4HxhBQFd_EIGa_P1xC9eVdy8sQ',
summonerId: 'pPWUsvk_67FuF7ky1waWDM_gho-3NYP4enWTtte6deR3CjxOGoCfoIjjNw',
});
};
export const resetDb = async () => {
await wipeDb();
await seed();
};
Sometimes I find that firestore has 4 records, other times it has 0 records, 2 records and so on .. I don't know why I await the promises before each test.
I expect to keep the same state before each test, can you help me please?
CodePudding user response:
All the problem was the parallel behavior of jest, I just needed to run the tests sequentially with the param --runInBand
or maxWorkers=1