使用反应测试库时无法读取反应本机平面列表中未定义的 属性
Cannot read property of undefined in react native flat list when using react testing library
我正在尝试使用 react-testing-library 在 react native 中创建一个简单的快照测试,但我不明白为什么我会收到“无法读取 属性 'lines'不明确的”。 flatlist 可以很好地呈现数据,但测试不会通过。
我也试过解构 summary.lines,但也没用。
● 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 | />
模拟 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;
这是因为在初始渲染中 summary.lines
由于异步调用而未定义。
要解决此问题,请添加 ?
它会在执行前进行空检查
data={summary?.lines}
看起来您正在获取的摘要数据来自异步调用,因此在初始点,它是未定义的。
在这种情况下,添加空检查有助于解决此类问题。尝试 summary?.lines
.
而不是 summary.lines
我正在尝试使用 react-testing-library 在 react native 中创建一个简单的快照测试,但我不明白为什么我会收到“无法读取 属性 'lines'不明确的”。 flatlist 可以很好地呈现数据,但测试不会通过。
我也试过解构 summary.lines,但也没用。
● 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 | />
模拟 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;
这是因为在初始渲染中 summary.lines
由于异步调用而未定义。
要解决此问题,请添加 ?
它会在执行前进行空检查
data={summary?.lines}
看起来您正在获取的摘要数据来自异步调用,因此在初始点,它是未定义的。
在这种情况下,添加空检查有助于解决此类问题。尝试 summary?.lines
.
summary.lines