lundi 15 juin 2020

Simple Jest test is failing (Salesforce LWC)

Hello i have a very simple LWC component that runs on a custom record, it takes in the rec id as a parameter calls apex, and displayed the response message to the user.

The issue i am having is when writing a Jest test for this i encounter errors even though my component / test is basically identical to the one seen in the examples: (https://github.com/trailheadapps/lwc-recipes/tree/master/force-app/main/default/lwc/apexImperativeMethod)

Can anyone help me correct this test so that it no longer fails / causes the other tests to fail?

The error i keep seeing is:

    TypeError: syncData is not a function

  19 |
  20 |     connectedCallback() {
> 21 |         syncData({rec: this.recordId})
     |         ^
  22 |          .then (response => {
  23 |              this.syncMessage = response;
  24 |              this.syncDone = true;

Below is the HTML of my LWC:

<template>
    <div>
        <p><b>{label.Data_Sync_Heading}</b></p>
        <p>{syncMessage}</p>
    </div>
</template>

Below is the .js of my LWC:

import { LightningElement, api, track } from 'lwc';
import syncData from '@salesforce/apex/DataController.syncData';
import Data_Sync_Fail from '@salesforce/label/c.Data_Sync_Fail';
import Data_Sync_Default_Message from '@salesforce/label/c.Data_Sync_Default_Message';
import Data_Sync_Heading from '@salesforce/label/c.Data_Sync_Heading';



export default class syncDataLwc extends LightningElement {
    @api recordId;

    @track syncMessage = Data_Sync_Default_Message;
    @track syncDone = false;

    // Expose the labels to use in the template.
    label = {
        Data_Sync_Heading
    };

    connectedCallback() {
        syncData({rec: this.recordId})
         .then (response => {
             this.syncMessage = response;
             this.syncDone = true;
         })
         .catch(() => {
             this.syncMessage = Data_Sync_Fail;
             this.syncDone = true;
         });
    }

Below is the .JEST test code for my LWC:

import { createElement } from 'lwc';
import syncDataLwc from 'c/syncDataLwc';
import Data_Sync_Fail from '@salesforce/label/c.Data_Sync_Fail';
import Data_Sync_Heading from '@salesforce/label/c.Data_Sync_Heading';
import syncData from '@salesforce/apex/DataController.syncData';

let element;

//mock out the text for the heading label
jest.mock("@salesforce/label/c.Data_Sync_Heading", () => {
    return { default: "Sync Data" };
}, { virtual: true });

//mock out the text for the default failure message label
jest.mock("@salesforce/label/c.Data_Sync_Fail", () => {
    return { default: "Failed to Synchronise Data. Data could be out of date." };
}, { virtual: true });



// ----- adding the apex mock causes all tests to fail, when not mocked tests work as exspected.

// Mocking syncData Apex method call
jest.mock('@salesforce/apex/DataController.syncData', () => {
     return {default: jest.fn()};
}, { virtual: true });


// Sample error for imperative Apex call
const APEX_REC_SUCCESS =  "this is a test";



describe('c-sync-Data-lwc', () => {

    //This line of code is necessary to reset the DOM after each block of test code
    afterEach(() => {
        while (document.body.firstChild) {
            jest.clearAllMocks();
            document.body.removeChild(document.body.firstChild);
        }
    }); 

    // Helper function to wait until the microtask queue is empty. This is needed for promise
    // timing when calling imperative Apex.
    function flushPromises() {
        // eslint-disable-next-line no-undef
        return new Promise((resolve) => setImmediate(resolve));
    }

    //An it block describes a single test. A test represents a single functional unit that you want to test. Write the it to describe the expected behavior of that function.
    it('CUSTOM LABEL TEST: Custom label for the heading was mocked with the default value', () => {

        // Create initial element
        const element = createElement('c-syncDataLwc', {
            is: syncDataLwc
        });
        document.body.appendChild(element);

        return flushPromises().then(() =>  {
            const paragraphs = element.shadowRoot.querySelectorAll('p');
            expect(paragraphs.length).toBe(2);

            const boldHeading = element.shadowRoot.querySelectorAll('b');
            expect(boldHeading.length).toBe(1);


            expect(boldHeading[0].textContent).toBe("Sync Data");
        });
    });


//This is failing.
    it('APEX RETURN SUCESS: checking that the default error is used when apex call fails', () => {


        const REC_ID = '001';
        const APEX_PARAMETERS = { rec: REC_ID };


        // Create initial element
        const element = createElement('c-syncDataLwc', {
            is: syncDataLwc
        });
        document.body.appendChild(element);

        // Assign mock value for resolved Apex promise
        syncData.mockResolvedValue(APEX_REC_SUCCESS);

        return flushPromises().then(() =>  {

           //get the paragraphs on the html page
           const paragraphs = element.shadowRoot.querySelectorAll('p');

            //check the text is = to the sucess mock
            expect(paragraphs[1].textContent).toBe(
                APEX_REC_SUCCESS
            );

        });
    });
});

Aucun commentaire:

Enregistrer un commentaire