LWC Unit Testing with Jest

If you are familiar with the Salesforce ecosystem, you are well aware of how crucial it is to test almost all of the features you intend to use or deploy. This is also applicable to the CRM’s most recent development model, Lightning Web Components. Although LWC testing is not (yet) particularly common, Jest offers a straightforward testing environment to ensure that your LWCs are precise, valid, and reliable. Today’s topic will be covering Unit Testing LWC with Jest, the famous and well-known JavaScript testing framework.

Why do we need to Unit Test LWC?

Since it is virtually impossible to have software without bugs, testing our code the best way possible is one of the safest bets to ensure the quality of the products we develop. Lightning Web Components are rapidly becoming the preferred way of developing for Salesforce programmers due to their multiple advantages – flexibility, adaptability to modern UIs, ease of development, improved performance, and many more. With such a powerful tool, comes great responsibility – making sure they work as intended. With Jest, you will be able to run tests on your LWC in a simple, guided manner, not to mention the quality assurance of your final product, leading to increased client satisfaction.

Previous steps

Before beginning your Unit Testing with Jest journey, there exist a few requirements you need to go through. First of all, make sure to install Node.js together with npm. There’s no need to worry much about npm because it is automatically installed when implementing Node.js.

After that, you must install sfdx-lwc-jest and its dependencies into each Salesforce DX project. The simplest way to do this is to run the Salesforce CLI command sfdx force:lightning:lwc:test:setup. By running this command, you create the necessary configuration files and install the sfdx-lwc-jest package.

If you work in a setting where the Salesforce CLI isn’t available, you can configure your test dependencies on your own. Type npm install and npm install @salesforce/sfdx-lwc-jest -save-dev to get started.

Concluding this section, it is worth noting that if your SFDX does not include these script entries in the script block of its package.json file, you should add them:

... {   
"scripts": {    
  ...     
  "test": "npm run test:unit",     
  "test:unit": "sfdx-lwc-jest",     
  "test:unit:watch": "sfdx-lwc-jest --watch",     
  "test:unit:debug": "sfdx-lwc-jest --debug",     
  "test:unit:coverage": "sfdx-lwc-jest --coverage",     
  ...   
 },   
... 
}

For more information, refer to the official documentation in the Developer Guide.

Jest tests walkthrough & parts

For the sake of simplicity, we are going to cover the specifics of Jest testing with Lightning Web Components – The details of the Jest framework are well covered in the Jest documentation. It is necessary to know that the tests should focus on a particular component’s behavior in isolation with little to no reliance on other components or services. To exemplify this article, we used a LWC and Jest tests from Trailhead’s Github repository lwc-recipes. All rights go to their respective owners. Coming back to the article, all Jest tests must use the following structure:

Imports

The test imports the createElement method, only available in tests, for then to import the component to test.

describe block

describe block defines a test suite, which consists of one or more tests that, from the perspective of functionality, are related. In the official documentation, it is recommended to have a top-level describe block with a description matching the component name. If needed, you may add more describe blocks – for instance, to group things into categories like error scenarios, empty input, and so forth.

Cleanup

In this section, we make use of the afterEach() method, which resets the DOM at the end of the test. Jest uses the Node.js project jsdom to give a setting that functions very similarly to the DOM or document of a browser. Changes are not reset between tests inside a test file since each test file shares a single instance of jsdom. However, Jest can employ alternative techniques for setup and cleanup work.

it (or test) block

The it block describes a single test, and you may use it to describe the expected behavior of that function. For example, if you have a component displaying “Hello, World!”, the it block tests that this component displays said greeting.

Adding the component to the DOM

The method appendChild is called to insert the component into the DOM, and the Lightning framework connectedCallback() and renderedCallback() methods are called.

Afterward, Jest uses a standard DOM query method to search the DOM for the element.shadowRoot as the parent for the query.

Asserts

Similarly to unit testing in Apex, asserts are invoked via the expect statement for the success condition. Jest supports matchers like toBe and toMatchObject in order to make sure a value meets a condition, therefore making testing even easier (in this case toBeAccessible() has been used).

Testing Asynchronous DOM Updates

If the state of the LWC changes, the DOM updates asynchronously. To avoid errors, Jest uses promises, a special object that stores its state, the current result (if there is any), and callbacks. In order to make it work, you need to chain the rest of your code to the resolved Promise. If the promise ends in the rejected state, Jest fails the test.

It is worth noting that the component is rendered synchronously if the attribute is set before the appendChild() operation. On the other hand, you don’t have to wait for asynchronous updates or return a promise if the property is set before the appendChild() function.

Jest unit testing @wire LWC

The well-known and useful wire service is used to get data from Salesforce. In order to test the components that make use of it, Jest makes the utility @salesforce/sfdx-lwc-jest available for us to use. It is important to mock the test data in the sense that your test is not dependent on unpredictable and possible factors – such as remote invocation or server latency, which would make the test run wrongly.

Instead of getting data from Salesforce, you need to create a JSON that defines the (mock) data that the component expects. There are three steps in order to test components that use @wire:

First of all, create a JS class named componentName.test.js inside the __tests__ folder (you may create it in your LWC if it does not exist). Then, add a JSON file called wireAdapter.json, in which you will mock the data that the wire adapter emits. In the previously created JS class file, import the component under test and its wire adapter, as well as the mock data from the JSON file. Make sure to emit the mock data and verify that the component is receiving it.

It is important to note that mocks can be stored in the __mocks__ subdirectory rather than the __data__ one. You can simulate the required functions in a different file inside this folder to make them easier to read. Just keep in mind to remove instances and calls from mock constructors and methods after each test has finished running.

Running Jest tests

As part of Node.js, Jest tests are run on the command line – in our case by using Salesforce CLI commands. If you use VS Code and have the Salesforce extensions installed, you can run tests, debug them, and watch Jest files within the IDE. If you use any other IDE, you may run the sfdx force:lightning:lwc:test:run from the root folder of your project. Apart from that, you may execute the command you put to the scripts block of your project’s package.json file, as described in the «Previous steps» section: npm run test:unit.

If you wish to run all tests for a single component every time you save changes, you may use the command npm run test:unit:watch. This way, every time Jest notices a change, it runs all pertinent tests and checks all component files for changes.

It may be useful to run tests in debug mode if you want to step through your tests and app code to find out why your tests or code are not behaving as expected.

Debugging Jest tests

The Salesforce developer documentation provides three different methods or ways to debug Jest tests efficiently: VS Code’s Salesforce extension pack, Chrome DevTools, or the VS Code debugger advanced configuration, based on your needs. We are going to briefly cover each one of them.

You may quickly run tests using the LWC Tests sidebar that is provided by the Salesforce Extensions for Visual Studio Code. You are provided with different execution options: a single test case, every test case included in a single file, or every test for your project.

In order to make debugging easier, you may add breakpoints in the test by clicking next to the line number on the left side of the screen. The debug toolbar also allows you to go through the execution of a test and breakpoints. Additionally, any output from a test execution can be viewed in the VS Code terminal.

With the aforementioned VS Code debugger advanced configuration, you can set up how you wish to run your Jest tests in debug mode.

For web development, Chrome DevTools offer thorough diagnostic features. Enter the following command to run a single test in debug mode, where testName is the name of the test you want to debug: runtest:unit:debug – testName with npm. Run it, then launch a new Chrome window and head to chrome:/inspect. To start debugging, add a debugger statement to your test code in Visual Studio Code and then click the inspect link under the Jest test displayed in the Remote Target section.

Your test code is now displayed, and the test will terminate at the debugger statement you added. Additionally, in the Source panel, you can add breakpoints for more effective debugging.

Recommended Best Practices

Salesforce’s Principal Developer Evangelist has written a very interesting and informative article about Jest testing, containing (among other things) a guide for the best practices regarding testing LWC. We are going to go through a few of them:

  • First and foremost, never combine various test cases into one test. A test ought to focus on a single functional area.
  • Following up, remember to clear your mocks before writing your @wire tests; otherwise, the testing may wind up failing.
  • The next recommended practice is to mock every base LWC; fortunately, Salesforce offers a default mock for you automatically. You can test function execution and attributes in this manner.
  • To conclude, you can test the behavior of the user interface (UI) in the event of a successful (or unsuccessful) load without actually using the resource while loading static resources. Alternatively, you can override the built-in mock implementation by loading the static resource.

If you would like to know more about best practices and recommendations for testing LWC with Jest, make sure to check out Salesforce’s Developer article linked in the Resources section.

Summary

Nowadays, developers have access to a high degree of quality assurance due to the capability of unit testing Lightning Web Components through Jest. Jest is often used, thus there is a ton of documentation, material, and advice on different web pages on testing with this framework, making it very accessible and approachable for Salesforce developers.

As Salesforce keeps shifting towards Lightning Web Components and transferring coding logic from apex to LWC, it is important to get familiarized with Jest testing, since it provides a well-put and competitive testing system. By learning how to develop Jest tests, you’re taking a step forward to developing reliable LWC and making sure that your code will be optimal, thoroughly checked, and running at its maximum efficiency.

Resources

https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.unit_testing_using_jest_create_tests
https://developer.salesforce.com/blogs/2019/03/unit-test-lightning-web-components-with-jest
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.unit_testing_using_jest_installation
https://www.salesforceben.com/how-to-use-jest-for-lightning-web-component-testing
https://www.mirketa.com/hands-on-lwc-jest-unit-testing
https://techkasetti.com/blog/index.php/2021/02/18/jest-unit-testing-with-lwc
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.unit_testing_using_wire_utility
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.unit_testing_using_jest_debug_tests
https://github.com/trailheadapps/lwc-recipes

ARTÍCULOS RECIENTES