How to perform LWC + Jest: Assert about what happens before a wire adapter returns data?

846    Asked by dipesh_9001 in Salesforce , Asked on Apr 24, 2021

I have a LWC with a wired function hooked up to the getFiles method in an Apex class, like this:  myLwc.html myLwc.js

import { LightningElement, api, track, wire } from "lwc"; import getFiles from "@salesforce/apex/MyApexController.getFiles"; export default class MyLwc extends LightningElement { @track files; showSpinner = true; @wire(getFiles, { recordId: "$recordId" }) loadFiles({ data, error }) { if (data) { this.files = data; } else if (error) { // ... } console.log("setting showSpinner to false"); this.showSpinner = false; } }
I want to write a test that asserts that the spinner appears in the DOM until the wired function gets its return value or errors. I'm trying to do it like this:

myLwc.test.js

import { createElement } from "lwc"; import { registerApexTestWireAdapter } from "@salesforce/sfdx-lwc-jest"; import myLwc from "c/myLwc"; import { getRecord } from "lightning/uiRecordApi"; // Set up wired data mocking const mockGetFiles = require("./data/getFiles.json"); const getFilesWireAdapter = registerApexTestWireAdapter(getFiles); // eslint-disable-next-line no-undef const flushPromises = () => new Promise(setImmediate); describe("crmOppFiles tests", () => { afterEach(() => { while (document.body.firstChild) { document.body.removeChild(document.body.firstChild); } }); it("shows the spinner until files are loaded", async () => { console.log("starting test"); const element = createElement("c-my-lwc", { is: myLwc }); element.recordId = "OPP001"; // Add the component to the DOM document.body.appendChild(element); console.log("after appendChild"); // The spinner should be present initially const spinner = element.shadowRoot.querySelector("lightning-spinner"); expect(spinner).toBeTruthy(); // IT FAILS HERE // Simulate the getRecord wire service returning data getFilesWireAdapter.emit(mockGetFiles); // Wait for all async processes to complete await flushPromises(); // Now that all initial data retrieval is complete, the spinner should // be hidden expect(spinner).toBeFalsy(); }); });
My console output shows up in the following order...

starting test setting showSpinner to false after appendChildb ... which tells me the LWC framework doesn't actually wait until you call getRecordWireAdapter.emit() to execute the wired function. That being the case, is there any way to test for conditions that are present before the wire service returns a response (like spinners, etc)?

Answered by Csaba Toth

I had performed a closer inspection on my lwc, I found out that the @wire-decorated function gets called immediately when the component loads, before there is an actual response. data and error are both undefined in that call. So my assumption that the function only got called based on a true data/error response was misplaced. Rewriting my LWC is like this, now the test passes:

            @wire(getFiles, { recordId: "$recordId" }) loadFiles({ data, error }) { if (data) { this.files = data; } else if (error) { // ... } if (data || error) { this.showSpinner = false; } }

Hope this works!



Your Answer

Interviews

Parent Categories