# Testing ## Jest To test a component which use RNCamera, you need to create a react-native-camera.js file inside your __mocks__ folder on the root of your project with the following content: ```javascript import React from 'react' const timeout = ms => new Promise(resolve => setTimeout(resolve, ms)) export class RNCamera extends React.Component { static Constants = { Aspect: {}, BarCodeType: {}, Type: { back: 'back', front: 'front' }, CaptureMode: {}, CaptureTarget: {}, CaptureQuality: {}, Orientation: {}, FlashMode: {}, TorchMode: {}, } takePictureAsync = async () => { await timeout(2000) return { base64: 'base64string', } } render() { return null } } export default RNCamera ``` You don't need to do anything else in your test, because Jest will use the mock in your test instead of the native module. ### Example We are going to create a component which uses RNCamera which two simple features: - Take a photo - Change camera between front or back The custom component PhotoCamera is the following: ```javascript import React from 'react' import { View, TouchableOpacity, StyleSheet, Dimensions } from 'react-native' import { RNCamera } from 'react-native-camera' import Icon from 'react-native-vector-icons/FontAwesome' const styles = StyleSheet.create({ container: { flex: 1, display: 'flex', flexDirection: 'column', backgroundColor: 'black', }, preview: { flex: 1, justifyContent: 'flex-end', alignItems: 'center', }, topButtons: { flex: 1, width: Dimensions.get('window').width, alignItems: 'flex-start', }, bottomButtons: { flex: 1, width: Dimensions.get('window').width, justifyContent: 'flex-end', alignItems: 'center', }, flipButton: { flex: 1, marginTop: 20, right: 20, alignSelf: 'flex-end', }, recordingButton: { marginBottom: 10, }, }) class PhotoCamera extends React.PureComponent { state = { type: RNCamera.Constants.Type.back, } flipCamera = () => this.setState({ type: this.state.type === RNCamera.Constants.Type.back ? RNCamera.Constants.Type.front : RNCamera.Constants.Type.back }) takePhoto = async () => { const { onTakePhoto } = this.props const options = { quality: 0.5, base64: true, width: 300, height: 300, } const data = await this.camera.takePictureAsync(options) onTakePhoto(data.base64) } render() { const { type } = this.state return ( { this.camera = cam }} type={type} style={styles.preview} /> ) } } export default PhotoCamera ``` And here is our test to check if it renders properly: ```javascript import React from 'react' import Adapter from 'enzyme-adapter-react-16' import { shallow, configure } from 'enzyme' import MyPhotoCamera from './' configure({ adapter: new Adapter() }) describe('PhotoCamera Tests', () => { test('renders correctly', () => { const wrapper = shallow() expect(wrapper).toMatchSnapshot() }) }) ``` Also, here is the complete test of the whole component with 100% coverage: ```javascript import React from 'react' import { TouchableOpacity } from 'react-native' import Adapter from 'enzyme-adapter-react-16' import { shallow, configure, mount } from 'enzyme' import PhotoCamera from '../' const { JSDOM } = require('jsdom') const jsdom = new JSDOM() const { window } = jsdom function copyProps(src, target) { const props = Object.getOwnPropertyNames(src) .filter(prop => typeof target[prop] === 'undefined') .map(prop => Object.getOwnPropertyDescriptor(src, prop)) Object.defineProperties(target, props) } global.window = window global.document = window.document global.navigator = { userAgent: 'node.js', } copyProps(window, global) // Ignore React Web errors when using React Native // but still show relevant errors const suppressedErrors = /(React does not recognize the.*prop on a DOM element|Unknown event handler property|is using uppercase HTML|Received `true` for a non-boolean attribute `accessible`|The tag.*is unrecognized in this browser)|is using incorrect casing|Received `true` for a non-boolean attribute `enabled`/ const realConsoleError = console.error // eslint-disable-line // eslint-disable-next-line console.error = message => { if (message.match(suppressedErrors)) { return } realConsoleError(message) } configure({ adapter: new Adapter() }) describe('PhotoCamera Tests', () => { test('renders correctly', () => { const wrapper = shallow() expect(wrapper).toMatchSnapshot() }) test('initial state should be back camera', () => { const wrapper = shallow() expect(wrapper.state().type).toBe('back') }) test('should flip the camera from back to front', () => { const wrapper = shallow() expect(wrapper.state().type).toBe('back') wrapper .find(TouchableOpacity) .first() .props() .onPress() expect(wrapper.state().type).toBe('front') }) test('should flip the camera from front to back if touch flip button and curren state is ', () => { const wrapper = shallow() wrapper.setState({ type: 'front', }) wrapper.update() wrapper .find(TouchableOpacity) .first() .props() .onPress() expect(wrapper.state().type).toBe('back') }) test('should have a reference to the React Native Camera module', () => { const wrapper = mount() expect(wrapper.instance().camera).toBeDefined() }) test('test onPress functionality', async () => { const onTakePhotoEvent = jest.fn(data => data) const wrapper = mount() await wrapper .find(TouchableOpacity) .at(1) .props() .onPress() expect(onTakePhotoEvent.mock.calls.length).toBe(1) }) }) ```