I'm trying to create a simple snapshot test in react native using react-testing-library, but I can't figure out why I am getting "cannot read property 'lines' of undefined". The flatlist is rendering the data fine with no issues, but the test wont pass.
I've also tried destructuring out the summary.lines, but that didn't work either.
● Single Collection Screen Renders
TypeError: Cannot read property 'lines' of undefined
47 | <FlatList
> 48 | data={summary.lines}
| ^
49 | renderItem={renderCollectionOrderLines}
50 | keyExtractor={(_item, i) => i.toString()}
51 | />
Mock data.js:
export const useSingleOrdersMock = [
{
order_number: 'ABC/1234',
date: '25/06/20',
order_status: 'Processing',
order_total: '£1000.25',
delivery_address: {
name: 'John Doe',
short_name: 'Example Address',
line_1: 'Example Street',
line_2: 'United Kingdom',
line_3: null,
line_4: null,
line_5: null,
postcode: 'ABC 123',
},
invoice_address: {
name: 'Steve Smith',
short_name: 'Example Address',
line_1: 'Example Street',
line_2: 'United Kingdom',
line_3: null,
line_4: null,
line_5: null,
postcode: 'ABC 123',
},
summary: {
subtotal: '£1100.25',
delivery: 'Free',
vat: '£100',
lines: [
{
product_id: 123456,
part_code: 'ABC1234',
stock_code: '01234-5678',
description: 'Combi Oven',
quantity: 1,
price_including_vat: '10.20',
price_excluding_vat: '8.50',
vat: '1.70',
},
{
product_id: 678910,
part_code: 'ABC1234',
stock_code: '01234-5678',
description: 'Combi Oven',
quantity: 1,
price_including_vat: '5.10',
price_excluding_vat: '4.25',
vat: '0.85',
},
],
},
},
];
export const SingleCollectionScreenAccountContext = {
selectedCollectionOrder: useSingleOrdersMock,
setSelectedCollectionOrder: jest.fn(),
};
Test.js:
test('Single Collection Screen Renders', () => {
let tree;
act(() => {
tree = renderer.create(
<ScreenRenderer
additionalAccountContext={SingleCollectionScreenAccountContext}>
<SingleCollectionScreen />
</ScreenRenderer>,
);
});
expect(tree.toJSON()).toMatchSnapshot();
});
Component.js
import React from 'react';
import { ScrollView, FlatList } from 'react-native';
import Row from '../../components/Account/Row';
import { useAccountContext } from '../../providers/AccountProvider';
const SingleCollectionScreen = () => {
const { selectedCollectionOrder } = useAccountContext();
const {
order_number,
order_total,
summary,
} = selectedCollectionOrder;
// const { lines } = summary
const renderCollectionOrderLines = ({ item }) => {
const {
description,
part_code,
price_excluding_vat,
quantity,
stock_code,
} = item;
return (
<SummaryLine
itemName={description}
catalogue={part_code}
priceExVat={price_excluding_vat}
quantity={quantity}
stockCode={stock_code}
/>
);
};
return (
<ScrollView>
<ScreenContainer>
<FlatList
data={summary.lines} <-- error occurring here
renderItem={renderCollectionOrderLines}
keyExtractor={(_item, i) => i.toString()}
/>
<Row title="Subtotal" value={summary.subtotal} />
<Row title="Delivery" value={summary.delivery} />
<Row title="VAT" value={summary.vat} />
<Row title="Total" value={orderTotal} highlight />
</ScreenContainer>
</ScrollView>
);
};
export default SingleCollectionScreen;
CodePudding user response:
It's because in the initial rendering summary.lines is getting undefined.
To get rid of this issue add a ? it will take that as an optional and only execute when summary?.lines is not undefined
data={summary?.lines}
CodePudding user response:
Looks like the summary data you are getting, is from an asynchronous call, thus at the initial point, its undefined.
In such scenario adding a null check helps in resolving such issues. Instead of summary.lines, try summary?.lines.
