5

I have a LWC component which performs multiple operations in connectedCallback(), one of them is a registerListener which calls an apex method which updates a record in the DB. Here is my question: How can I test the function called by the listener?. The listener is being called, but I can not get the callback function to run. Thanks in advance.

Fragment of the code. line 43 registerListener. I can not get coverage of the function inline 52

connectedCallback() {
    //first load call the methods
    if (!sessionStorage.getItem('sessionId')) {
      this.handleFormFactor();
      this.handleOS();
      this.handleBrowser();
      this.handleGeolocation();
    }
    //refresh get data from sessionStorage
    else {
      this.sessionId = sessionStorage.getItem('sessionId');
      this.sessionRecord = JSON.parse(sessionStorage.getItem('session'));
    }
    //register listeners from PreAppContainer and trigger unload functionality
    registerListener('registerLastPage', this.register, this);
    window.addEventListener('unload', this.unloadHandler.bind(this));
  }

  disconnectedCallback() {
    unregisterAllListeners(this);
  }

  //Register event from PreApp Container and get the last page visited
  register(mes) {
    if (mes.lastPage != 'type') {
      this.updateRecord(this.sessionRecord, mes.message);
    }
  }

  //update session record with the last page visited by the user
  updateRecord(session, last) {
    let sessionString = JSON.stringify(session);
    console.log('in update ' + sessionString);
    updateSessionRecord({ payload: sessionString, lastPage: last })
      .then(result => console.log(result.Last_Page__c))
      .catch(error => console.log(error));
  }

Fragment of the Jest Test class

    it('test registerListener Update', () => {
        insertSession.mockResolvedValue(APEX_SESSION_SUCCESS);
        const element = createElement('c-ab-testing', {
            is: AbTesting
        });
        const fetch = (global.fetch = mockFetch(FETCH_DATA));
        document.body.appendChild(element);
        //testing register listeners
        //expect(registerListener.mock.calls.length).toBe(2);
        expect(registerListener.mock.calls[0][0]).toBe('registerLastPage');

        let callback = registerListener.mock.calls[0][1];
        //FAILING HERE//ATTRIBUTE NULL
        callback.call(MESSAGE_DATA);

        return flushPromises().then(() => {
            //testing that fetch is being called
            expect(fetch).toHaveBeenCalledTimes(1);
            expect(fetch.mock.calls[0][0]).toBe(QUERY_URL); 
            //testing that the record is being inserted
            expect(insertSession.mock.calls[0][0]).not.toEqual(null);
        });
    });
2
  • 1
  • Hi @Alba Rivas, I followed that link with no success, in the article the callback function does not require any attribute, in my case I'm passing the response of the listener to the callback. At least I'm able to call the function (that is good progress), but I'm getting an error in the code that the attribute of the function is null. You can see in my Jest test method, I have comments on the line throwing the error. Thank you. Oct 7, 2020 at 21:08

1 Answer 1

3

One option that you have is to manually call the callback, to simulate that an event has occurred, passing an arbitrary payload. I don't see all your code, but assuming that we have the next implementation (taken from an example in lwc-recipes):

...    
connectedCallback() {
    registerListener('contactSelected', this.handleContactSelected, this);
}
    
handleContactSelected(contactId) {
    this.recordId = contactId;
}
...

You can do:

// Call callback function manually
const contactId = '12345678';
const callback = registerListener.mock.calls[0][1];
callback.call(element, contactId);

// Expect that callback has been called with the expected payload
expect(element.recordId).toBe(contactId);

I tried out myself and it worked, not sure why you're receiving a null callback function but let me know if this works. Also check that you're setting up the mock correctly doing:

jest.mock('c/pubsub', () => {
    return {
        registerListener: jest.fn(),
        unregisterAllListeners: jest.fn()
    };
});
1
  • Great, I was passing 'this' instead of the 'element'. Thank you for taking the time. Oct 8, 2020 at 13:55

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.