Skip to content
πŸ¦… Custom jest matchers to test the state of React Native
Branch: master
Clone or download
allcontributors and bcarroll22 docs: add SantiMA10 as a contributor (#5)
* docs: update README.md

* docs: update .all-contributorsrc
Latest commit 006f50a May 23, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
other docs(readme): update documentation Apr 5, 2019
src chore(tests): fix breaking test with latest NTL version May 16, 2019
.all-contributorsrc docs: add SantiMA10 as a contributor (#5) May 23, 2019
.gitattributes initial commit Apr 4, 2019
.gitignore initial commit Apr 4, 2019
.npmrc initial commit Apr 4, 2019
.travis.yml ci: move codecov to test phase [ci skip] Apr 16, 2019
CHANGELOG.md initial commit Apr 4, 2019
CODE_OF_CONDUCT.md docs: add all_contributors Apr 16, 2019
LICENSE add licsense Apr 4, 2019
README.md docs: add SantiMA10 as a contributor (#5) May 23, 2019
babel.config.js babel preset and bump NTL Apr 30, 2019
extend-expect.d.ts feat: support breaking changes for native-testing-library preset (#2) Apr 28, 2019
extend-expect.js feat: update tests to use baseElement Apr 6, 2019
jest.config.js feat: support breaking changes for native-testing-library preset (#2) Apr 28, 2019
package.json fix: add types to package.json (#4) May 23, 2019
setup-tests.js

README.md

jest-native

goat

Custom jest matchers to test the state of React Native.


Build Status Code Coverage version downloads MIT License

All Contributors PRs Welcome Code of Conduct

Watch on GitHub Star on GitHub

Table of Contents

The problem

You want to use jest to write tests that assert various things about the state of a React Native app. As part of that goal, you want to avoid all the repetitive patterns that arise in doing so like checking for a native element's props, its text content, its styles, and more.

This solution

The jest-native library provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain.

Compatibility

These matchers should, for the most part, be agnostic enough to work with any React Native testing utilities, but they are primarily intended to be used with native-testing-library. Any issues raised with existing matchers or any newly proposed matchers must be viewed through compatibility with that library and its guiding principles first.

Installation

This module should be installed as one of your project's devDependencies:

npm install --save-dev jest-native

You will need native-testing-library, react, and react-native installed in order to use this package.

Usage

Import jest-native/extend-expect once (for instance in your tests setup file) and you're good to go:

import 'jest-native/extend-expect';

Alternatively, you can selectively import only the matchers you intend to use, and extend jest's expect yourself:

import { toBeEmpty, toHaveTextContent } from 'jest-native';

expect.extend({ toBeEmpty, toHaveTextContent });

Matchers

jest-native has only been tested to work with native-testing-library. Keep in mind that these queries will only work on UI elements that bridge to native.

toBeDisabled

toBeDisabled();

Check whether or not an element is disabled from a user perspective.

This matcher will check if the element or its parent has a disabled prop, or if it has accessibilityStates={['disabled']}.

Examples

const { getByTestId } = render(
  <View>
    <Button disabled testID="button" title="submit" onPress={e => e} />
    <TextInput accessibilityStates={['disabled']} testID="input" value="text" />
  </View>,
);

expect(getByTestId('button')).toBeDisabled();
expect(getByTestId('input')).toBeDisabled();

toBeEnabled

toBeEnabled();

Check whether or not an element is enabled from a user perspective.

Works similarly to expect().not.toBeDisabled().

Examples

const { getByTestId } = render(
  <View>
    <Button testID="button" title="submit" onPress={e => e} />
    <TextInput testID="input" value="text" />
  </View>,
);

expect(getByTestId('button')).toBeEnabled();
expect(getByTestId('input')).toBeEnabled();

toBeEmpty

toBeEmpty();

Check that the given element has no content.

Examples

const { getByTestId } = render(<View testID="empty" />);

expect(getByTestId('empty')).toBeEmpty();

toContainElement

toContainElement(element: ReactTestInstance | null);

Check if an element contains another element as a descendant. Again, will only work for native elements.

Examples

const { queryByTestId } = render(
  <View testID="grandparent">
    <View testID="parent">
      <View testID="child" />
    </View>
    <Text testID="text-element" />
  </View>,
);

const grandparent = queryByTestId('grandparent');
const parent = queryByTestId('parent');
const child = queryByTestId('child');
const textElement = queryByTestId('text-element');

expect(grandparent).toContainElement(parent);
expect(grandparent).toContainElement(child);
expect(grandparent).toContainElement(textElement);
expect(parent).toContainElement(child);
expect(parent).not.toContainElement(grandparent);

toHaveProp

toHaveProp(prop: string, value?: any);

Check that an element has a given prop. Only works for native elements, so this is similar to checking for attributes in the DOM.

You can optionally check that the attribute has a specific expected value.

Examples

const { queryByTestId } = render(
  <View>
    <Text allowFontScaling={false} testID="text">
      text
    </Text>
    <Button disabled testID="button" title="ok" />
  </View>,
);

expect(queryByTestId('button')).toHaveProp('accessibilityStates', ['disabled']);
expect(queryByTestId('button')).toHaveProp('accessible');
expect(queryByTestId('button')).not.toHaveProp('disabled');
expect(queryByTestId('button')).not.toHaveProp('title', 'ok');

toHaveTextContent

toHaveTextContent(text: string | RegExp, options?: { normalizeWhitespace: boolean });

Check if an element has the supplied text.

This will perform a partial, case-sensitive match when a string match is provided. To perform a case-insensitive match, you can use a RegExp with the /i modifier.

To enforce matching the complete text content, pass a RegExp.

Examples

const { queryByTestId } = render(<Text testID="count-value">2</Text>);

expect(queryByTestId('count-value')).toHaveTextContent('2');
expect(queryByTestId('count-value')).toHaveTextContent(2);
expect(queryByTestId('count-value')).toHaveTextContent(/2/);
expect(queryByTestId('count-value')).not.toHaveTextContent('21');

toHaveStyle

toHaveStyle(style: object[] | object);

Check if an element has the supplied styles.

You can pass either an object of React Native style properties, or an array of objects with style properties. You cannot pass properties from a React Native stylesheet..

Examples

const styles = StyleSheet.create({ text: { fontSize: 16 } });

const { queryByText } = render(
  <Text style={[{ color: 'black', fontWeight: '600' }, styles.text]}>Hello World</Text>,
);

expect(queryByText('Hello World')).toHaveStyle({ color: 'black', fontWeight: '600', fontSize: 16 });
expect(queryByText('Hello World')).toHaveStyle({ color: 'black' });
expect(queryByText('Hello World')).toHaveStyle({ fontWeight: '600' });
expect(queryByText('Hello World')).toHaveStyle({ fontSize: 16 });
expect(queryByText('Hello World')).toHaveStyle([{ color: 'black' }, { fontWeight: '600' }]);
expect(queryByText('Hello World')).not.toHaveStyle({ color: 'white' });

Inspiration

This library was made to be a companion for native-testing-library.

It was inspired by jest-dom, the companion library for dom-testing-library. We emulated as many of those helpers as we could while keeping in mind the guiding principles.

Other solutions

None known, you can add the first!

Contributors

Thanks goes to these wonderful people (emoji key):

Brandon Carroll
Brandon Carroll

πŸ’» πŸ“– πŸš‡ ⚠️
Santi
Santi

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

You can’t perform that action at this time.