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 Preferences
DisplayItems.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 testID
s. 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