我正在使用React Native构建我的应用程序,我使用Jest和Enzyme进行单元测试。我怎样才能测试我的<FlatList />
的renderItem()
功能?
它从React-Native-Elements库返回一个<ListItem />
。
我来给你一个示例代码:
import { ListItem } from 'react-native-elements'
export class MyList extends Component {
const list = [
{
name: 'Amy Farha',
subtitle: 'Vice President'
},
{
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
subtitle: 'Vice Chairman'
},
... // more items
]
keyExtractor = (item, index) => index
renderItem = ({ item }) => (
<ListItem
title={item.name}
subtitle={item.subtitle}
leftAvatar={{
source: item.avatar_url && { uri: item.avatar_url },
title: item.name[0]
}}
/>
)
render () {
return (
<FlatList
keyExtractor={this.keyExtractor}
data={this.state.dataSource}
renderItem={this.renderItem}
/>
)
}
}
我希望能够测试renderItem()
功能。我的问题是,wrapper.instance().renderItem({item: item})
返回错误:TypeError: wrapper.instance(...).renderItem(...).find is not a function
。让我给你我写的测试代码:
describe("component methods", () => {
let wrapper;
let props;
let item;
beforeEach(() => {
props = createTestProps();
wrapper = shallow(<MyList {...props} />);
});
describe("renderItem", () => {
describe("user", () => {
beforeEach(() => {
item = {
name: 'Chris Jackson',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
subtitle: 'Vice Chairman'
};
});
it("should display the order as a <ListItem />", () => {
expect(
wrapper
.instance()
.renderItem(item)
.find("ListItem")
).toHaveLength(1);
});
});
});
});
我怎么能写这个测试,以便我可以测试函数是否正确呈现<ListItem />
?
你可以用FlatList
测试react-native-testing-library
这是一个例子:
const Item = ({ name ) => <Text>{name}</Text>
class LisItem extends React.Component {
_keyExtractor = (item: { id: string }) => item.id
render() {
return (
<View style={styles.container}>
{todos && (
<FlatList
data={this.props.todos}
keyExtractor={this._keyExtractor}
renderItem={({ item: { id, name } }) => (
<Item
key={id}
name={name}
/>
)}
/>
)}
</View>
)
}
}
import { render } from 'react-native-testing-library'
const mockDataTodos = [
{
id: 'id-1',
name: 'Todo-1',
},
{
id: 'id-2',
name: 'Todo-2',
},
{
id: 'id-3',
name: 'Todo-3',
},
]
describe('Testing FlatList', () => {
test('Error component should be render when error is true', () => {
const componentTree = render(
<ListItem todos={mockDataTodos} />,
)
expect(componentTree.getAllByType(FlatList).length).toBe(1)
expect(componentTree.getAllByType(Item).length).toBe(mockDataTodos.length)
})
})
希望这有帮助!
renderItem()
返回一个JSX元素。 JSX compiles to React.createElement() which returns an object。
因此,renderItem()
的返回值只是一个对象。
您可以通过执行以下操作来测试renderItem()
是否创建了正确的对象:
it("should display the order as a <ListItem />", () => {
const element = wrapper
.instance()
.renderItem(item);
expect(element.type).toBe(ListItem);
expect(element.props).toEqual({
title: 'Chris Jackson',
subtitle: 'Vice Chairman',
leftAvatar: {
source: { uri: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg' },
title: 'C'
}
});
});
所以我不确定你是否从基于类的组件中提取了一些代码,但renderItem
本身就是一个组件。我可以给你一些测试代码,你可以根据自己的需要进行调整,假设你导入了浅层并设置了你的item变量:
describe('renderItem', () => {
it('should display as a ListItem', () => {
const wrapper = shallow(<renderItem item={item} />);
expect(wrapper.find(ListItem).length).toEqual(1);
});
});
有两个与您的示例不同的关键事项。一个 - 我在这里假设您已经将ListItem
导入您的测试中。然后你可以直接将它传递给find
。第二位是你要将查找和检查长度的结果传递给expect
并测试其值。想想它是“我想要测试的东西”(它可以找到的ListItem
组件的数量),然后你创建你的断言(toEqual(1)
)。
在你的设置中,我不打算直接测试renderItem
。相反,我会确保对ListItem
进行全面测试,然后断言MyList
如何呈现FlatList
。这可以使用expect(wrapper).toMatchSnapshot()
来完成,甚至更好地通过断言给予FlatList
的道具的一些事情。如果你对这一切真的很偏执,也许使用mount
而不是浅浅来完全呈现它。