I have a Lightning Web Component "dapUserList".
This is the HTML:
<template>
<lightning-card title="User List" icon-name="utility:user">
<c-errors errors={errors}></c-errors>
<template lwc:if={showNoUsers}>
<p>No users returned.</p>
</template>
<template lwc:else>
<ul>
<template for:each={users} for:item="user">
<c-dap-user-item key={user.id} user={user}></c-dap-user-item>
</template>
</ul>
</template>
</lightning-card>
</template>
and this is the JavaScript:
import { LightningElement, track } from 'lwc';
import { reduceErrors } from 'c/ldsUtilities';
import getDummyApiUsers from '@salesforce/apex/DAP_DummyApiProxyAuraCtrl.getDummyApiUsers';
export default class DapUserList extends LightningElement {
@track users = [];
@track errors = false;
connectedCallback() {
getDummyApiUsers()
.then(users => {
if (users) {
this.users = users;
this.errors = false;
}
})
.catch(error => {
this.users = [];
this.errors = reduceErrors(error);
});
}
get showNoUsers() {
return !this.errors && !this.users?.length;
}
}
I'm trying to prove an instance of c-dap-user-item
occurs for each user returns from the server.
I've created these tests:
import { LightningElement, track } from 'lwc';
import { createElement } from 'lwc';
import { reduceErrors } from 'c/ldsUtilities';
import DapUserList from 'c/dapUserList';
import getDummyApiUsers from '@salesforce/apex/DAP_DummyApiProxyAuraCtrl.getDummyApiUsers';
const mockGetDummyApiUsersWithMultipleUsers = require('./data/getDummyApiUsersWithMultipleUsers.json');
const mockGetDummyApiUsersWithNoUsers = require('./data/getDummyApiUsersWithNoUsers.json');
const mockGetDummyApiUsersWithOneUser = require('./data/getDummyApiUsersWithOneUser.json');
jest.mock(
'@salesforce/apex/DAP_DummyApiProxyAuraCtrl.getDummyApiUsers',
() => {
const {
createApexTestWireAdapter
} = require('@salesforce/sfdx-lwc-jest');
return {
default: createApexTestWireAdapter(jest.fn())
};
},
{ virtual: true }
);
const elementUnderTest = 'c-dap-user-list';
const childUserElement = 'c-dap-user-item';
describe(elementUnderTest, () => {
afterEach(() => {
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
jest.clearAllMocks();
});
describe('getDummyApiUsers @wire data', () => {
it('renders one user', () => {
// Arrange
getDummyApiUsers.mockResolvedValue(mockGetDummyApiUsersWithOneUser);
const element = createElement(elementUnderTest, {
is: DapUserList
});
// Act
document.body.appendChild(element);
return Promise.resolve()
.then(() => {
// Assert
const userElements = element.shadowRoot.querySelectorAll(childUserElement);
expect(userElements.length).toBe(mockGetDummyApiUsersWithOneUser.length);
});
});
it('renders multiple users', () => {
// Arrange
getDummyApiUsers.mockResolvedValue(mockGetDummyApiUsersWithMultipleUsers);
const element = createElement(elementUnderTest, {
is: DapUserList
});
// Act
document.body.appendChild(element);
return Promise.resolve()
.then(() => {
// Assert
const userElements = element.shadowRoot.querySelectorAll(childUserElement);
expect(userElements.length).toBe(mockGetDummyApiUsersWithMultipleUsers.length);
});
});
it('renders no users', () => {
// Arrange
getDummyApiUsers.mockResolvedValue(mockGetDummyApiUsersWithNoUsers);
const element = createElement(elementUnderTest, {
is: DapUserList
});
// Act
document.body.appendChild(element);
return Promise.resolve()
.then(() => {
// Assert
const userElements = element.shadowRoot.querySelectorAll(childUserElement);
expect(userElements.length).toBe(mockGetDummyApiUsersWithNoUsers.length);
const noUsersMessage = element.shadowRoot.querySelector('p');
expect(noUsersMessage).not.toBeNull();
expect(noUsersMessage.textContent).toBe('No users returned.');
});
});
});
});
The first two fail because element.shadowRoot.querySelectorAll(childUserElement)
never returns any elements.
I think this is because they will only be rendered after connectedCallback()
is executed and I don't think this is executing.
I've tried including element.connectedCallback();
in the test, but this results in "TypeError: element.connectedCallback is not a function" ... It does not seem connectedCallback() is visible to the tests. If we have some JavaScript equivalent for
@TestVisible` we could add, I'm not aware of it, and I expect using it would be considered a bad practice anyway.
So, what's the right way to fix these tests?