Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test that the renderItem function returns a <ListItem />?

I'm building my app with React Native and I do my unit tests with Jest and Enzyme. How can I test my <FlatList />'s renderItem() function?

It returns a <ListItem /> from the React-Native-Elements library.

Let me give you the example code:

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}
      />
    )
  }
}

I would like to be able to test the renderItem() function. My problem is, that wrapper.instance().renderItem({item: item}) returns the error: TypeError: wrapper.instance(...).renderItem(...).find is not a function. Let me give you the code of the test that I wrote:

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);
      });
    });
  });
});

How would I have to write this test so that I can test if the function correctly renders a <ListItem />?

like image 619
J. Hesters Avatar asked Aug 25 '18 12:08

J. Hesters


People also ask

What is renderItem in FlatList?

renderItem({ item, index, separators }); Takes an item from data and renders it into the list.

What is renderItem?

renderItem: It is used to render the data into the list. data: It is basically an array of data. ItemSeparatorComponent: It is used to render in between each item. ListEmptyComponent: It is rendered when the list is empty. ListFooterComponent: It is rendered at the bottom of all items.

What is the use of keyExtractor in FlatList?

It extracts the unique key name and its value and tells the FlatList component to track the items based on that value.


2 Answers

You can also test using the renderProp function.

const wrapper = shallow(<YourComponent {...defaultProps} />);
const flatList = wrapper.find('FlatList');

const item = flatList.renderProp('renderItem')({ item: yourData });
expect(item).toMatchSnapshot();
like image 199
Denys Makhov Avatar answered Oct 04 '22 18:10

Denys Makhov


renderItem() returns a JSX element. JSX compiles to React.createElement() which returns an object.

Therefore, the return value from renderItem() is just an object.

You can test that renderItem() creates the correct object by doing the following:

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'
    }
  });
});
like image 22
Brian Adams Avatar answered Oct 04 '22 20:10

Brian Adams