Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue when test connectedCallback method on LWC component that use more that one module mock #304

Open
vdyn opened this issue Feb 10, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@vdyn
Copy link

vdyn commented Feb 10, 2023

Description

connectedCallback method does not complete calls to mock modules before tests start.

Steps to Reproduce

customComponent.js

import {api, LightningElement} from "lwc";
import getResult01 from "@salesforce/apex/Controller01.getResult01";
import getResult02 from "@salesforce/apex/Controller02.getResult02";

export default class CustomComponent extends LightningElement {

    value01;
    value02;

    @api
    getValue01() {
        return this.value01;
    }

    @api
    getValue02() {
        return this.value02;
    }

    async connectedCallback() {
        await this.initialization();
    }

    @api
    async customMethod() {
        await this.initialization();
    }

    async initialization() {
        console.log("starting callback");

        const result01 = await getResult01();
        console.log("result 01 is", result01);
        this.value01 = result01.field0101;

        const result02 = await getResult02();
        console.log("result 02 is", result02);
        this.value02 = result02.field0201;

        console.log("ending callback");
    }
}

customComponent.test.js

import {createElement} from 'lwc';
import getResult01 from "@salesforce/apex/Controller01.getResult01";
import getResult02 from "@salesforce/apex/Controller02.getResult02";
import CustomComponent from "../customComponent";

jest.mock(
    "@salesforce/apex/Controller01.getResult01",
    () => {
        return {default: jest.fn()};
    },
    {virtual: true}
);

jest.mock(
    "@salesforce/apex/Controller02.getResult02",
    () => {
        return {default: jest.fn()};
    },
    {virtual: true}
);

async function flushPromises() {
    return Promise.resolve();
}

const createComponent = async (attributes) => {
    const element = createElement("custom-component", {
        is: CustomComponent
    });
    Object.assign(element, attributes);
    document.body.appendChild(element);

    await flushPromises();
    return element;
};

describe("custom component test", () => {

    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
        jest.clearAllMocks();
    });

    it("connectedCallback", async () => {
        getResult01.mockResolvedValue({
            field0101: "a",
            field0102: "b"
        });
        getResult02.mockResolvedValue({
            field0201: "c",
            field0202: "d"
        });
        const element = await createComponent();
        window.console.log("value 01", element.getValue01());
        window.console.log("value 02", element.getValue02());
    });

    it("customMethod", async () => {
        getResult01.mockResolvedValue({
            field0101: "a",
            field0102: "b"
        });
        getResult02.mockResolvedValue({
            field0201: "c",
            field0202: "d"
        });
        const element = await createComponent();
        await element.customMethod();
        window.console.log("value 01", element.getValue01());
        window.console.log("value 02", element.getValue02());
    });
});

Expected Results

First tests work as expected. Please note that the second test is for check the correct code flow.

Actual Results

First test fails. The first value (the result to call getResult01) is correct, but the second value (the result to call getResult02) is undefined.

Version

  • @salesforce/sfdx-lwc-jest: 1.1.0
  • Node: 18.12.0

Possible Solution

No solution found.

Additional context/Screenshots

  • Run the test one by time
  • To run the second test comment the connectedCallback method (to avoid confusions)
@BatemanVO
Copy link

I copy/pasted the code and ran the test and both pass for me:

PASS force-app/main/default/lwc/customComponent/__tests__/customComponent.test.js
  custom component test
    √ connectedCallback (143 ms)
    √ customMethod (15 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.918 s
Ran all test suites matching /force-app\\main\\default\\lwc\\customComponent\\/i.

Using:

  • sfdx-lwc-jest: 1.4.1
  • Node: 18.9.0
  • Windows 10

Can you consolidate the Apex into a single call? It seems strange to make two calls to Apex in a connectedCallback instead of a single call that would return the data both calls would make, since each call is a separate trip to the server and it would be more efficient to bundle the needed data in a single call.

For example, if you have:

@AuraEnabled
public static Map<String, String> getResult01() {
    return new Map<String, String>{
        'field0101' => 'a',
        'field0102' => 'b'
    };
}

@AuraEnabled
public static Map<String, String> getResult02() {
    return new Map<String, String>{
        'field0201' => 'c',
        'field0202' => 'd'
    };
}

Then you could do something like:

public static Map<String, String> getResult01() {
    return new Map<String, String>{
        'field0101' => 'a',
        'field0102' => 'b'
    };
}

public static Map<String, String> getResult02() {
    return new Map<String, String>{
        'field0201' => 'c',
        'field0202' => 'd'
    };
}

@AuraEnabled
public static Map<String, Map<String, String>> getResults() {
    return new Map<String, Map<String, String>>{
        'result01' => getResult01(),
        'result02' => getResult02()
    };
}

And in the initialization:

async initialization() {
    const results = await getResults();
    this.value01 = results.result01.field0101;
    this.value02 = results.result02.field0201;
}

@nolanlawson nolanlawson added the bug Something isn't working label Aug 10, 2023
@nolanlawson
Copy link
Contributor

@vdyn Could you provide a GitHub repo with the necessary code and steps to reproduce the issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants