Custom jest matchers to test the state of React Native
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Jest Native provides custom Jest matchers specifically designed for testing React Native components and applications. It extends Jest's assertion capabilities with React Native-specific matchers that understand component states, accessibility properties, and React Native-specific behaviors like visibility, styling, and component hierarchy relationships.
npm install --save-dev @testing-library/jest-nativeimport '@testing-library/jest-native/extend-expect';For selective imports:
import { toBeDisabled, toHaveTextContent, toHaveStyle } from '@testing-library/jest-native';
expect.extend({ toBeDisabled, toHaveTextContent, toHaveStyle });import { render } from '@testing-library/react-native';
import '@testing-library/jest-native/extend-expect';
const MyComponent = () => (
<View>
<Text testID="greeting">Hello World</Text>
<TextInput testID="input" value="test" editable={false} />
<Button title="Submit" disabled={true} />
</View>
);
test('component rendering and states', () => {
const { getByTestId, getByText } = render(<MyComponent />);
// Text content assertion
expect(getByTestId('greeting')).toHaveTextContent('Hello World');
// Disabled state assertion
expect(getByTestId('input')).toBeDisabled();
expect(getByText('Submit')).toBeDisabled();
// Visibility assertion
expect(getByTestId('greeting')).toBeVisible();
});Jest Native extends Jest's expect object with custom matchers that work with ReactTestInstance objects from react-test-renderer. The matchers are designed to:
Test whether React Native elements are enabled or disabled based on component props and accessibility states.
/**
* Tests if a React Native element is disabled
*/
toBeDisabled(): jest.MatcherResult;
/**
* Tests if a React Native element is enabled (opposite of disabled)
*/
toBeEnabled(): jest.MatcherResult;Usage Examples:
// Button disabled state
expect(getByText('Submit')).toBeDisabled();
expect(getByText('Cancel')).toBeEnabled();
// TextInput editable state
expect(getByTestId('readonly-input')).toBeDisabled();
expect(getByTestId('editable-input')).toBeEnabled();
// Accessibility-based disabled state
expect(getByLabelText('Disabled Button')).toBeDisabled();Test whether React Native elements have specific content or are empty.
/**
* Tests if a React Native element has no children
*/
toBeEmptyElement(): jest.MatcherResult;
/**
* Tests if a React Native element has specific text content
* @param text - Text to match (string or regex)
*/
toHaveTextContent(text: string | RegExp): jest.MatcherResult;
/**
* @deprecated Use toBeEmptyElement instead
*/
toBeEmpty(): jest.MatcherResult;Usage Examples:
// Text content matching
expect(getByTestId('title')).toHaveTextContent('Welcome');
expect(getByTestId('description')).toHaveTextContent(/Hello.*World/);
// Empty element testing
expect(getByTestId('empty-container')).toBeEmptyElement();Test whether React Native elements are visible or present on the screen.
/**
* Tests if a React Native element is visible
*/
toBeVisible(): jest.MatcherResult;
/**
* Tests if a React Native element is present on the screen
*/
toBeOnTheScreen(): jest.MatcherResult;Usage Examples:
// Visibility testing
expect(getByTestId('modal')).toBeVisible();
expect(getByTestId('hidden-element')).not.toBeVisible();
// Screen presence testing
expect(getByTestId('rendered-component')).toBeOnTheScreen();Test parent-child relationships between React Native elements.
/**
* Tests if a React Native element contains another element
* @param element - The element to check for containment
*/
toContainElement(element: ReactTestInstance | null): jest.MatcherResult;Usage Examples:
// Element containment
const container = getByTestId('container');
const child = getByTestId('child');
expect(container).toContainElement(child);
// Nested component testing
const form = getByTestId('form');
const submitButton = getByText('Submit');
expect(form).toContainElement(submitButton);Test React Native element props and styling.
/**
* Tests if a React Native element has a specific prop with optional value check
* @param attr - Property name to check
* @param value - Expected value of the property (optional)
*/
toHaveProp(attr: string, value?: unknown): jest.MatcherResult;
/**
* Tests if a React Native element has specific styles
* @param style - Style object to match
*/
toHaveStyle(style: StyleProp<ViewStyle | TextStyle | ImageStyle>): jest.MatcherResult;Usage Examples:
// Prop testing
expect(getByTestId('input')).toHaveProp('placeholder', 'Enter text');
expect(getByTestId('image')).toHaveProp('source');
// Style testing
expect(getByTestId('title')).toHaveStyle({
fontSize: 24,
fontWeight: 'bold',
color: '#333'
});
expect(getByTestId('container')).toHaveStyle({
flexDirection: 'row',
justifyContent: 'center'
});Test React Native accessibility states and values.
/**
* Tests if a React Native element has specific accessibility state
* @param state - Expected accessibility state object
*/
toHaveAccessibilityState(state: AccessibilityState): jest.MatcherResult;
/**
* Tests if a React Native element has specific accessibility value
* @param value - Expected accessibility value matcher
*/
toHaveAccessibilityValue(value: AccessibilityValueMatcher): jest.MatcherResult;Usage Examples:
// Accessibility state testing
expect(getByLabelText('Toggle')).toHaveAccessibilityState({
disabled: false,
selected: true
});
expect(getByTestId('checkbox')).toHaveAccessibilityState({
checked: true
});
// Accessibility value testing
expect(getByLabelText('Volume')).toHaveAccessibilityValue({
min: 0,
max: 100,
now: 50
});
expect(getByLabelText('Progress')).toHaveAccessibilityValue({
text: '50% complete'
});/**
* Accessibility value matcher interface
*/
interface AccessibilityValueMatcher {
min?: number;
max?: number;
now?: number;
text?: string | RegExp;
}
/**
* Jest Native matchers interface
*/
interface JestNativeMatchers<R> {
toBeDisabled(): R;
toBeEmptyElement(): R;
toBeEnabled(): R;
toBeOnTheScreen(): R;
toBeVisible(): R;
toContainElement(element: ReactTestInstance | null): R;
toHaveTextContent(text: string | RegExp): R;
toHaveProp(attr: string, value?: unknown): R;
toHaveStyle(style: StyleProp<ViewStyle | TextStyle | ImageStyle>): R;
toHaveAccessibilityState(state: AccessibilityState): R;
toHaveAccessibilityValue(value: AccessibilityValueMatcher): R;
/** @deprecated Use toBeEmptyElement instead */
toBeEmpty(): R;
}// jest-setup.ts
import '@testing-library/jest-native/extend-expect';For compatibility with older Jest versions or specific configurations:
// jest-setup.ts
import '@testing-library/jest-native/legacy-extend-expect';This adds matchers with legacy_ prefix (e.g., legacy_toBeDisabled).
Add to declarations.d.ts:
/// <reference types="@testing-library/jest-native" />Or use the TypeScript Jest setup file approach shown above.
All matchers provide detailed error messages with:
.not)