如何测试 renderItem 函数是否返回 <ListItem />?

J. *_*ers 9 listitem jestjs react-native enzyme react-native-flatlist

我正在使用 React Native 构建我的应用程序,并使用 Jest 和 Enzyme 进行单元测试。如何测试 my<FlatList />renderItem()功能?

<ListItem />从 React-Native-Elements 库返回一个。

让我给你示例代码:

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}
      />
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望能够测试该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);
      });
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

我必须如何编写此测试才能测试该函数是否正确呈现<ListItem />?

Huy*_*yen 8

您可以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>
    )
  }
}

Run Code Online (Sandbox Code Playgroud)

单元测试:

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)
    })
})
Run Code Online (Sandbox Code Playgroud)

希望这有帮助!

  • 关于 getAllByType 的注意事项“不鼓励使用它们”,https://callstack.github.io/react-native-testing-library/docs/migration-v2/#removed-functions (2认同)

Bri*_*ams 7

renderItem()返回一个 JSX 元素。 JSX 编译为 React.createElement() ,它返回一个 object

因此, from 的返回值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'
    }
  });
});
Run Code Online (Sandbox Code Playgroud)