Hooking up components
There are two parts to writing Cavy tests: registering the components you'd like to test so that Cavy knows about them, and writing the test cases.
In this section, we'll cover using Cavy's generateTestHook
function to
hook up the components you want to interact with in your tests.
How does this work?
Cavy uses React ref generating functions.
We'll pass our components a ref using generateTestHook
, which returns the
ref generating function that adds components to the TestHookStore
, making them
available to us in our specs.
generateTestHook
takes a string as an argument, which is the identifier
we'll use in our tests to reference the component. It can be anything you
like - make sure to use something that is easy to understand to keep your tests
readable!
There are two ways of getting access to generateTestHook
:
- using
useCavy()
React Hook - the modern approach - using
hook()
function - the older approach
For testing function components that cannot be assigned a ref directly, you can
use Cavy's wrap
function to create testable versions of
these components. You will also need to wrap
native components like Text
,
TextInput
, TouchableOpacity
, TouchableHighlight
and Pressable
.
useCavy()
React Hook
If you're using React Hooks, you can call the custom useCavy()
React Hook to
obtain the generateTestHook
function and assign a ref to the component you
want to test:
import { Button } from 'react-native';
import { useCavy } from 'cavy';
export default () => {
const generateTestHook = useCavy();
return (
<Button
ref={generateTestHook('Scene.Button')}
onPress={...}
/>
)
};
hook()
function
Cavy also provides a hook
function which makes generateTestHook
available as
in props. As assign a red to the component you want to test and then export a
hooked version of your parent component:
import React from 'react';
import { Button } from 'react-native';
import { hook } from 'cavy';
class Scene extends React.Component {
render() {
return (
<Button
ref={this.props.generateTestHook('Scene.Button')}
onPress={...}
/>
);
}
}
const TestableScene = hook(Scene);
export default TestableScene;
wrap()
function
You can use Cavy's wrap
function to achieve two things:
1. Testing function components
If you'd like to test a function component to which you can't assign a ref (for
example if you're importing a third-party function component), create a testable
version of it using the wrap
function, then assign it a ref as normal using
generateTestHook
:
import { FunctionComponent } from 'some-ui-library';
import { useCavy, wrap } from 'cavy';
export default () => {
const generateTestHook = useCavy();
const TestableFunctionComponent = wrap(FunctionComponent);
return (
<TestableFunctionComponent
ref={generateTestHook('Scene.FunctionComponent')}
/>
)
};
<Text>
, <TextInput>
, <Pressable>
, <TouchableOpacity>
and <TouchableHighlight>
2. Testing native components like If you want to test any of these components using Cavy helper functions, or by accessing their props directly yourself, you must wrap them first:
import { Text } from 'react-native';
import { useCavy, wrap } from 'cavy';
export default () => {
const generateTestHook = useCavy();
const TestableText = wrap(Text);
return (
<TestableText
ref={generateTestHook('Scene.Text')}
/>
)
};
If you assign a ref directly to these specific components, the component returned does not expose the props. Therefore, Cavy will not be able to peform actions on them in your tests.
Note: If you only want to test the presence of a these components, you do not need to wrap it before assigning it a ref.