'race problem with mocha unit testing Firestore onSnapshot, test ends before onSnapshot returns data
I have a function I'm testing. It's called from the constructor on an object.
constructor(authorID: string) {
this.loadRecipes(authorID)
}
private loadRecipes = (author_id: string) => {
const first = query(collection(db, "cookbook"), where("author_id", "==", author_id));
this._unsubscribe = onSnapshot(first, (querySnapshot) => {
this._recipes = [];
querySnapshot.forEach((doc) => {
this._recipes.push(new Recipe(doc.id, doc.data().author_id, "", "", -1, "draft", [], [], [], 0, ""));
});
});
};
I'm calling it from a mocha test:
it("Creates a recipe list by author ID", () => {
authorRecipes = new RecipeList(author_id);
assert(authorRecipes.list.length>0);
});
The code works fine, but the test fails. The problem is that the test completes running long before the onSnapshot ever fires and populates the list. Is there a way to force the query to populate - sort of like an async/await? Or a way to force mocha to wait? Setting a breakpoint & debugging, the onSnapshot is eventually called so the code works. I just cannot do any follow on tests because the data isn't there yet.
Solution 1:[1]
I ended up adding a "loading" flag to the class:
private loadRecipes = (author_id: string, _max?: number, _start?: number) => {
this._loading = true;
const first = query(collection(db, "cookbook"), where("author_id", "==", author_id));
this._unsubscribe = onSnapshot(first, (querySnapshot) => {
this._recipes = [];
querySnapshot.forEach((doc) => {
this._recipes.push(new Recipe(doc.id, doc.data().author_id, "", "", -1, "draft", [], [], [], 0, ""));
});
this._loading = false;
});
};
And then watched the flag with a delay in the test:
it("Creates a recipe list by author ID", async () => {
authorRecipes = new RecipeList(author_id);
while (authorRecipes.loading) {
await timeout(1000);
}
assert(!authorRecipes.loading);
});
Not super elegant, but gets the job done.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Wayne Culbreth |
