[SalesForce] Testing LWC with multiple @wire getRecord calls with Jest

I thought this would be straight-forward, but it turns out to be a complete nightmare. Found no help on google, in the lwc-recipes or documentation.

Here's my issue: I have a LWC that makes multiple asynchronous server calls, two of them use the same getRecord method from lightning/uiRecordApi.

    @wire(getRecord, {recordId : '$opportunityId', fields: [
        OPPORTUNITY_STAGE_FIELD,
        OPPORTUNITY_SYNCED_QUOTE_STATUS_FIELD,
        OPPORTUNITY_CONTACT_ID,
        OPPORTUNITY_SYNCED_QUOTE_LINE_ITEM_COUNT,
        OPPORTUNITY_ACCOUNT_SHIPPING_ADDRESS_COMPLETE,
        OPPORTUNITY_ACCOUNT_BILLING_ADDRESS_COMPLETE
    ]})
    getOpportunity(result) {
        this.opportunity = result;
        this.contactId = getFieldValue(this.opportunity.data, OPPORTUNITY_CONTACT_ID);
    }

    @wire(getRecord, { recordId : '$contactId', fields: [CONTACT_EMAIL_FIELD]})
    contact;

    @wire(checkPermission)
    permission;

My code works: The data provisioned from getRecord is first written to the opportunity and then to the contact variable.

However, it turns out to be untestable. If I write it like this, the contact-data is written to both the opportunity and the contact variable. If I only emit OPPORTUNITY_VALID, both variables have the opportunity data.

test('valid opportunity and valid contact => submit button enabled', async () => {

    const element = createElement('c-create-order-from-opportunity', {
        is: createOrder 
    });

    element.opportunityId = OPPORTUNITY_VALID.id;
    getRecordWireAdapter.emit(OPPORTUNITY_VALID);
    getRecordWireAdapter.emit(CONTACT_VALID);    
    checkPermissionWireAdapter.emit(true);

    document.body.appendChild(element);

    await Promise.resolve();

    let submitButton = element.shadowRoot.querySelector('[data-id="submitButton"]');
    expect(submitButton.disabled).toBe(false);

    let msgBoxes = element.shadowRoot.querySelectorAll('c-message-box');
    expect(msgBoxes.length).toBe(0);

});

I also tried to use Promise.resolve() between .emit() calls, but this did not work either.

Can anybody help me writing solid unit tests for a component that uses multiple independent @wired properties/functions with getRecord calls? My last resort would be to stop using getRecord in both instances and write my own apex method for getting the contact data so I can then mock the apex method.

Best Answer

This is a known gap in the wire service test utility. It's been around for a while, but we haven't forgotten about it. There's currently some non-trivial changes being made to the internals of how the wire service and wire adapters interact. As soon as those internal settle we will solve this testing gap.

The best place to follow along for a fix would be in the @salesforce/wire-service-jest-util github repo. The specific issue filed for this is here: https://github.com/salesforce/wire-service-jest-util/issues/15