Issue:
I have a list of Items that I want to test by each one of the items name value (string). I'm using @testing-library/react and have the test suite correctly working, but I can't get my test to work.
Overview:
item has a test id of data-testid="side-menu-link". Does this have to be unique or can it be tested as is?Dashboard, Settings, and User PreferencesDisplayItems.test.tsx:
// Imports: Dependencies
import React from 'react';
import { render, screen } from '@testing-library/react';
// Imports: App
import App from '../../App';
// Side Menu: Dashboard
test('Renders Dashboard correctly', () => {
// Render: App
const { getByTestId } = render(<App />);
// Expect
expect(getByTestId('side-menu-link')).toHaveAttribute('Dashboard')
});
// Side Menu: User Preferences
test('Renders Dashboard correctly', () => {
// Render: App
const { getByTestId } = render(<App />);
// Expect
expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')
});
Map Items:
// Map Menu Items
return menuItems.map((menuItem, i) => {
return (
<Link data-testid="side-menu-link" key={i} href="#" className="side-menu-link" to={`/${menuItem.itemName}`}>
<div className={props.currenttab === `${menuItem.itemName}` ? 'side-menu-item-container-selected-light' : 'side-menu-item-container-light'}>
{menuItem.itemIcon}
<p className={props.currenttab === `${menuItem.itemName}` ? 'side-menu-title-selected-light' : 'side-menu-title-light'}>{menuItem.itemName}</p>
</div>
</Link>
);
});
You can have multiple testIDs. Otherwise, there wouldn't be __AllByTestId selectors. The name wasn't well-thought out, it seems, because of similarity to HTML ids which must be unique.
A throw happens if you use __ByTestId yet you have multiple elements with the matching test id:
it("getByTestId will throw with multiple testIDs", () => {
const {getAllByTestId, getByTestId} = render(
<View>
<Text testID="foo">a</Text>
<Text testID="foo">b</Text>
</View>
);
expect(getAllByTestId("foo")).toHaveLength(2); // OK
getByTestId("foo"); // => Error: Found multiple elements with testID: foo
});
To test a map, you can add test ids to the children and use the above pattern.
React Native:
import "@testing-library/jest-native/extend-expect";
// ...
it("should find text content in all children", () => {
const {getAllByTestId} = render(
<View>
{[..."abcd"].map((e, i) =>
<View key={e + i} testID="foo"><Text>{e}</Text></View>
)}
</View>
);
expect(getAllByTestId("foo")).toHaveLength(4);
[..."abcd"].forEach((e, i) => {
expect(getAllByTestId("foo")[i]).toHaveTextContent(e);
});
});
React:
it("should find text content in all children", () => {
const {getAllByTestId} = render(
<ul>
{[..."abcd"].map((e, i) =>
<li key={e + i} data-testid="foo">{e}</li>
)}
</ul>
);
expect(getAllByTestId("foo")).toHaveLength(4);
[..."abcd"].forEach((e, i) => {
expect(getAllByTestId("foo")[i].textContent).toEqual(e);
});
// or:
//const contents = getAllByTestId("foo").map(e => e.textContent);
//expect(contents).toEqual([..."abcd"]);
});
It's also possible to add a testID to the parent of the mapped list elements, select the parent, then traverse over its .children array to make assertions on each child tree.
Note the differences between testID in RN and data-testid in React.
As a side note, I'm not sure
expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')
makes much sense here. attributes are <div this_is_an_attribute="foo"> -- you're probably looking for text content.
Packages used, for reference:
{
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-native": "^0.64.0",
"react-native-web": "^0.15.6"
},
"devDependencies": {
"@babel/core": "^7.13.15",
"@testing-library/jest-native": "^4.0.1",
"@testing-library/react-native": "^7.2.0",
"babel-jest": "^26.6.3",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.65.2",
"react-test-renderer": "^17.0.2"
}
}
{
"dependencies": {
"@babel/runtime": "7.10.5",
"react": "16.13.1",
"react-dom": "16.13.1",
},
"devDependencies": {
"@babel/core": "7.10.5",
"@babel/plugin-proposal-class-properties": "7.10.4",
"@babel/preset-env": "7.10.4",
"@babel/preset-react": "7.10.4",
"@testing-library/dom": "7.21.0",
"@testing-library/jest-dom": "^5.11.1",
"@testing-library/react": "10.4.7",
"@testing-library/react-hooks": "3.3.0",
"@testing-library/user-event": "12.0.11",
"babel-jest": "26.1.0",
"jest": "26.1.0",
"jest-environment-jsdom": "26.1.0",
"react-test-renderer": "16.13.1",
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With