I'm having an issue with testing toasts. I have read a lot about this thanks to google and followed the instructions but I can't seem to test my toast.
When I step through the test, I have a breakpoint on the line where the toast is thrown. This is so I know that the code is reaching the statement and not throwing any error.
I have also made sure that I have the file at ./force-app/test/test-mocks/lightning/platformShowToastEvent.js
So I am wondering what I am doing wrong.
Here's the code
import {LightningElement, api, wire} from 'lwc';
import {NavigationMixin} from 'lightning/navigation';
import {getFieldValue, getRecord} from "lightning/uiRecordApi";
import {ShowToastEvent} from "lightning/platformShowToastEvent";
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) => {
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) {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error',
message: 'this is bad',
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 is the test
import {createElement} from 'lwc';
import {getRecord} from 'lightning/uiRecordApi';
import {ShowToastEventName} from 'lightning/platformShowToastEvent';
import {
registerApexTestWireAdapter,
registerLdsTestWireAdapter,
} from '@salesforce/sfdx-lwc-jest';
import getLicenceAdministrators from '@salesforce/apex/ALSLicenceController.getLicenceAdministrators';
import getUserPermissions from '@salesforce/apex/ALSLicenceController.getUserPermissions';
import LicenceAdministratorsOnLicence from 'c/licenceAdministratorsOnLicence';
const mockedResponses = require('./data/mockedResponses.json');
const getLicenceAdministratorsAdapter = registerApexTestWireAdapter(getLicenceAdministrators);
const getUserPermissionsAdapter = registerApexTestWireAdapter(getUserPermissions);
const getLicenceAdapter = registerLdsTestWireAdapter(getRecord);
const getContactAdapter = registerLdsTestWireAdapter(getRecord);
jest.mock(
'@salesforce/apex/ALSLicenceController.addAdministrator',
() => {
return {
default: jest.fn(() => Promise.resolve({ data: {} }))
};
},
{ virtual: true }
);
describe('c-licence-administrators-on-licence', () => {
afterEach(() => {
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
});
it('submits and throws toast', () => {
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();
element.addEventListener(ShowToastEventName, showToastHandler);
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);
})
});
Best Answer
In this case, the call to the toast is in a chain of promises.
So in the end, this change is what worked:
If there's a better way to do this, I'd love to hear it. There is an issue with this 'setImmediate' call that you can read about in many other posts.
If you come across any issue with it, be sure to add this to your imports: