# 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)
})
})
```