7

The approaches suggested of using jestconfig module mapper or the mocks folder work well if you have a single mock per component you are testing, but not if you have to build how your parent component interacts with a child components in different scenario.

I would like to create a custom mock of my component in a specific jest test like so:

jest.mock('c/my-component', 
() => {
  return {
    default: jest.fn(),
    myExternalMethod: jest.fn( () => 'something')
  };
},
{ virtual: true })

however the following approach fails like so:

   Assert Violation: c() 2nd argument Ctor must be a function.

I imagine this is somehow related to the fact that c/my-component extends LightningComponent, but I cannot find any documentation about this. What is the right way to mock a specific custom LWC in a specific test?

1

1 Answer 1

0

Answer replicated from: How do I mock a child LWC in a parent's Jest Unit Test?

Let's say we have two components parentComponent and childComponent.

parentComponent includes childComponent in its template:

<template>
    <c-child-component
        child-property={aValue}
        other-child-property={anotherValue}
    ></c-child-component>
</template>

In order to mock childComponent only in the test for parentComponent we need to:

  • Build a skeleton stub for childComponent as a JS file.
  • Instruct the parentComponent test to use this file instead of the real childComponent.

Build a skeleton stub for childComponent as a JS file.

  • Create a folder inside the childComponent's folder named __mocks__.
  • Inside that folder, create a file childComponent.js, copying the contents of the real component into it. You should end up with a folder structure like:
    lwc
        childComponent
            __mocks__
                childComponent.js
            __tests__
                childComponent.test.js
            childComponent.html
            childComponent.js
            childComponent.js-meta.xml
  • Strip out everything from the new file other than the class definition and @api defined properties. E.g:
import { LightningElement, api } from 'lwc';

export default class SaveEntityForm extends LightningElement
{
    @api childProperty;
    @api otherChildProperty;
}
  • Ensure that the mocks folders are ignored when you perform a push by adding **/__mocks__/** into your .forceignore. E.g. it may look like:
package.xml

# LWC configuration files
**/jsconfig.json
**/.eslintrc.json

# LWC Jest
**/__tests__/**
**/__mocks__/**

Instruct the parentComponent test to use this file instead of the real childComponent.

  • At the top of the unit test for parentComponent, tell Jest to use the mock version of childComponent by calling jest.mock passing the Salesforce style import path of the component. E.g. the top of your test file may look like:
import { createElement } from 'lwc';
import ParentComponent from 'c/parentComponent';

jest.mock( 'c/childComponent' ); // Uses the mock version of childComponent defined in the __mocks__ directory of that LWC

describe( 'c-parent-component', () => {
    // your tests...
}

(thanks to https://tigerfacesystems.com/blog/lwc-nested-component-testing for the solution to this problem)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .