[SalesForce] How to mock custom LWC components in JEST

I am still new to JavaScript and especially Jest, so apologies in advance for the maybe stupid and uninformed question.

To isolate my tests, I want to mock one of my custom table components. In short, the custom component exposes a getModifiedRows() that returns all rows (another custom child component itself) with modifications (returning only the modified fields). The parent component using this table uses the getModifiedRows() to retrieve all modified rows (and some other stuff) and finally calls Apex to commit the data.

My plan is to mock getModifiedRows() in one specific test to return a defined list of "modifications" for this scenario. I assert on how my parent component uses this modifications.

I read alot in the following links and I am almost certain that somewhere, somehow there must be the solution to my problem. But I cant find it …

I tried this:

// parentComponent.test.js
jest.mock(
    './mocks/tableComponent',
    () => {
        return {
            default: jest.fn()
        };
    },
    { virtual: true }
);

// mocks/tableComponent.js
import { LightningElement, api } from 'lwc';
export default class TableComponent extends LightningElement {
    @api getModifiedRows() {return this.modifiedRows; }
    @api setModifiedRows(value) { this.modifiedRows= value; }
    modifiedRows;
}

but I was not able to mock any of the functions or override the value with the setModifiedRows() (which does not exist on the original component)

What is the syntax to mock a child component directly in the parentComponent.test.js?

Best Answer

Figured it out by myself, turns out to be pretty straight forward:

// childComponent.js
@api
getModifiedRows() {
    let arr = [];
    this.modifiedRowRecords.forEach( (value) => { arr.push(value); });
    return arr;
}
// parentComponent.test.js
let dataTable = element.shadowRoot.querySelector('c-child-component');
dataTable.getModifiedRows = jest.fn().mockImplementation(() => { return ['a052F000003tzKKQAY']; });

Any calls within my parent component to dataTable.getModifiedRows() will now return the mock array. This resets after each test, which is much more convenient than implementing my own mocks in separate files and updating jest configuration files.

Oddly enough, public properties/functions of element (e.g. the parent component under test) can not be mocked that way.

Related Topic