I'm trying to get my arms around testing LWC. I'm trying to test a button click that calls some Apex, then calls 'refreshApex' and then throws a success toast.
It seems I'm mocking my own custom Apex call ok. I'm not sure how to mock this 'refreshApex' call I'm using so that it returns a promise. I import it via
import {refreshApex} from "@salesforce/apex";
Here's the lwc:
import {NavigationMixin} from 'lightning/navigation';
import {getFieldValue, getRecord} from "lightning/uiRecordApi";
import {ShowToastEvent} from "lightning/platformShowToastEvent";
import {refreshApex} from "@salesforce/apex";
import {reduceErrors} from 'c/ldsUtils';
import addAdministratorRestCall
from '@salesforce/apex/ALSLicenceController.addAdministrator';
export default class LicenceAdministratorsOnLicence extends NavigationMixin(LightningElement) {
@api
recordId;
getAdministratorsResult;
selectedContactId;
@wire(getRecord, {recordId: '$recordId', fields: [LICENCE_GUID_FIELD]})
licence;
@wire(getRecord,
{recordId: '$selectedContactId', fields: [CONTACT_GUID_FIELD]})
selectedContact;
handleAdd() {
addAdministratorRestCall({
licenceGuid: this.licenceGuid,
contactGuid: this.selectedContactGuid
})
.then((result) => {
refreshApex(this.getAdministratorsResult);
})
.then((result) => {
this.throwSucceededToast('Licence Administrator added');
})
.catch((errors) => {
this.throwFailedToast(errors);
})
.finally(() => {
this.closeModal();
});
}
throwSucceededToast(message) {
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: message,
variant: 'success'
})
);
}
throwFailedToast(errors) {
let errorMsg = String(reduceErrors(errors));
this.dispatchEvent(
new ShowToastEvent({
title: 'Error',
message: errorMsg,
variant: 'error',
mode: 'sticky'
})
);
this.closeModal();
}
get licenceGuid() {
return getFieldValue(this.licence.data, LICENCE_GUID_FIELD);
}
get selectedContactGuid() {
return getFieldValue(this.selectedContact.data, CONTACT_GUID_FIELD);
}
}
here's the test:
import {createElement} from 'lwc';
import {getRecord} from 'lightning/uiRecordApi';
import {ShowToastEventName} from 'lightning/platformShowToastEvent';
import {registerApexTestWireAdapter, registerLdsTestWireAdapter} from '@salesforce/sfdx-lwc-jest';
// how do I mock this?
import {refreshApex} from "@salesforce/apex";
import addAdministratorRestCall from '@salesforce/apex/LicenceController.addAdministrator';
const mockedResponses = require('./data/mockedResponses.json');
const getLicenceAdministratorsAdapter = registerApexTestWireAdapter(getLicenceAdministrators);
const getLicenceAdapter = registerLdsTestWireAdapter(getRecord);
const getContactAdapter = registerLdsTestWireAdapter(getRecord);
const addAdministratorAdapter = registerApexTestWireAdapter(addAdministratorRestCall);
jest.mock(
'@salesforce/apex/LicenceController.addAdministrator',
() => {
return {
default: jest.fn(() => Promise.resolve({ data: {} }))
};
},
{ virtual: true }
);
it('handles contact change', () => {
const element = createElement('c-licence-administrators-on-licence', {
is: LicenceAdministratorsOnLicence
});
getLicenceAdministratorsAdapter.emit(mockedResponses.testAdministrators);
getUserPermissionsAdapter.emit(mockedResponses.allowed);
document.body.appendChild(element);
const showToastHandler = jest.fn();
const refreshApexHandler = jest.fn(() => Promise.resolve({ data: {} }));
element.addEventListener(ShowToastEventName, showToastHandler);
element.addEventListener(refreshApex, refreshApexHandler);
getLicenceAdapter.emit(mockedResponses.testLicence);
getContactAdapter.emit(mockedResponses.testContact);
return Promise.resolve().then(() => {
const addAdministratorButton = element.shadowRoot.querySelector("lightning-button[data-id=add-administrator]");
addAdministratorButton.click();
}).then(()=> {
const submitButton = element.shadowRoot.querySelector("lightning-button[data-id=submit-button]");
submitButton.click();
}).then(()=> {
expect(showToastHandler).toBeCalledTimes(1);
})
});
});
I appreciate any guidance
Best Answer
You need to mock the
refreshApex
module just like you mock the apex method modules as well.Then, in your actual tests you can assert it's been called however many times you expect
Or, provide a mock response to the refresh call before the test runs