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);
    });
});
9
  • I tried this code and it is working for me. Commented Jul 22, 2020 at 14:07
  • The code itself works, but lwc-jest complains and throws the error as stated in my question.
    – ceez
    Commented Jul 23, 2020 at 14:07
  • Sorry, I missed that, please add the test code as well. Commented Jul 23, 2020 at 14:18
  • I have added test code.
    – ceez
    Commented Jul 24, 2020 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
    Commented Nov 5, 2020 at 6:17

1 Answer 1

3
+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);
    });
  });
});
4
  • 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
    Commented Nov 5, 2020 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
    Commented Nov 5, 2020 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
    Commented Nov 5, 2020 at 13:55
  • 2
    Not necessarily and older version, it could also be a regression introduced later.
    – POZ
    Commented Nov 5, 2020 at 15:27

You must log in to answer this question.

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