4

I am trying to write Jest test for a component with two @wired calls (both bound to functions), but I get assertion error about property of second @wire call not being annotated with wire annotation. Error: Assert Violation: @wire on "handlePicklistResult": dot-notation reactive parameter "accountObjectInfo.defaultRecordTypeId" must refer to a @wire property

Any suggestions?

Here is sample code that I am trying to test:

import { LightningElement, wire, track } from 'lwc';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
import TYPE_FIELD from '@salesforce/schema/Account.Type';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';


export default class Democomponent extends LightningElement {
    @track accountObjectInfo;
    @track error;
    @track picklistValues;

    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    handleResult({error, data}) {
        if(data) {
            this.accountObjectInfo = data;
        } else {
            this.error = error;
        }
    }

    @wire(getPicklistValues, {recordTypeId: "$accountObjectInfo.defaultRecordTypeId", fieldApiName: TYPE_FIELD})
    handlePicklistResult({error, data}) {
        if(data) {
            this.picklistValues = data.values;
        } else {
            this.error = error;
        }
    }

}

Simple test I want to perform:

import {registerLdsTestWireAdapter} from '@salesforce/sfdx-lwc-jest';
import {createElement} from 'lwc';
import {getObjectInfo, getPicklistValues} from 'lightning/uiObjectInfoApi';
import TestPage from 'c/testPage';

const mockGetObjectInfo = require('./data/getObjectInfo.json');
const mockGetPicklistValues = require('./data/getPicklistValues.json');

const getObjectInfoAdapter = registerLdsTestWireAdapter(getObjectInfo);
const getPicklistValuesAdapter = registerLdsTestWireAdapter(getPicklistValues);

describe('c-test-page', () => {

    it('Should display test page', () => {
        const element = createElement('c-test-page', {
            is: TestPage
        });

        document.body.appendChild(element);

        getObjectInfoAdapter.emit(mockGetObjectInfo);
        getPicklistValuesAdapter.emit(mockGetPicklistValues);

        const picklistItems = element.shadowRoot.querySelectorAll('div.picklistItem');

        expect(picklistItems.length).toEqual(5);
    });
});
  • I tried this code and it is working for me. – rahul gawale Jul 22 at 14:07
  • The code itself works, but lwc-jest complains and throws the error as stated in my question. – ceez Jul 23 at 14:07
  • Sorry, I missed that, please add the test code as well. – rahul gawale Jul 23 at 14:18
  • I have added test code. – ceez Jul 24 at 12:40
  • @DavidReed Were you able to replicate this error? I'm unable to & this code works just fine for me. This could have been an issue from the past which has been already fixed in LWC. So, unless '@ceez' updates the code snippets (to help replicate this issue), I'm not sure if further troubleshooting can be done for this problem. – arut Nov 5 at 6:17
2
+75

There are several things that you need to correct in your test.

The most important one is that you don't need to fire both wires if you're just testing for the state of the template. Firing the getObjectInfo wire is not needed for this test because the test doesn't use the value of the recordTypeId parameter in the getPicklistValues test wire.

Then, you need to wait for the component to re-render after emitting data through the wire. We generally use a Promises.resolve() call to do that (see LWC Recipes).

Also, don't test with a hardcoded item length: expect(picklistItems.length).toEqual(5);. Use a dynamic value from your mock data instead: expect(picklistItems.length).toBe(mockGetPicklistValues.values.length);.

Here's the updated test that passes:

describe("c-test-page", () => {
  it("Should display test page", () => {
    const element = createElement("c-test-page", {
      is: TestPage
    });
    document.body.appendChild(element);

    getPicklistValuesAdapter.emit(mockGetPicklistValues);

    // Return a promise to wait for any asynchronous DOM updates. Jest
    // will automatically wait for the Promise chain to complete before
    // ending the test and fail the test if the promise rejects.
    return Promise.resolve().then(() => {
      const picklistItems = element.shadowRoot.querySelectorAll(
        ".picklistItem"
      );
      expect(picklistItems.length).toBe(mockGetPicklistValues.values.length);
    });
  });
});
| improve this answer | |
  • While all points in you answer are correct, were you able to replicate the original error posted in the question? I couldn't. The error message doesn't make any sense to me in the test JS (since, it will be using mock adapters). – arut Nov 5 at 12:57
  • 2
    No, I couldn't reproduce the error but it could be that @ceez is using a different version of sfdx-lwc-jest. I'm on the latest version (v0.10.2 for testing api v50.0). – POZ Nov 5 at 13:21
  • I felt that same must be the case. I'm on sfdx-lwc-jest v0.7.1. So, this may have been an issue with a much older version – arut Nov 5 at 13:55
  • 2
    Not necessarily and older version, it could also be a regression introduced later. – POZ Nov 5 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.