I have this code below in react-native using expo, which is a button, click on the button will call ImagePicker.requestMediaLibraryPermissionsAsync(), if the permission is granted, then call to ImagePicker.launchImageLibraryAsync() to let user pick the image.
I using React-native-testing-libary.
This code is working fine, but my jest test is keep failing, where it failed I tell below.
Here is my test, first I mock expo-image-picker module with the 2 function mentioned above and their resolved value :
import * as ImagePicker from 'expo-image-picker';
jest.mock('expo-image-picker', () => {
return {
requestMediaLibraryPermissionsAsync: jest.fn().mockResolvedValueOnce({
status: 'granted'
}),
launchImageLibraryAsync: jest.fn().mockResolvedValue({
cancelled: false, type: 'image',
uri: 'abc.jpeg',
width: '200',
height: '200'
})
}
})
Here is my code for your references:
import * as ImagePicker from 'expo-image-picker';
const requestPermission = async () => {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}else{
pickImage()
}
}
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
setImage(result.uri);
}
};
<Button title="Pick an image from camera roll" onPress={requestPermission} />
Then here is what I do in my test cases.
it('should pass test case ', () => {
const {getByTestId, queryByTestId, getByText} = render(<MyComponent />)
const pickImageButton = getByTestId('add_image')
// trigger the button
fireEvent.press(pickImageButton)
// request permission, here the resolved value is granted.
expect(ImagePicker.requestMediaLibraryPermissionsAsync).toBeCalledTimes(1)// here is pass
// choose from library this should be called
expect(ImagePicker.launchImageLibraryAsync).toBeCalledTimes(1) // test keep failing here
... other stuff here
})
As you can see, in my test cases, it will fires a button then it called to ImagePicker.requestMediaLibraryPermissionsAsync which will resolved status: 'granted' which is same with my code.
Since status:granted, then this function ImagePicker.launchImageLibraryAsync() should be called.
But right now, expect(ImagePicker.requestMediaLibraryPermissionsAsync).toBeCalledTimes(1) is pass, but this line expect(ImagePicker.launchImageLibraryAsync).toBeCalledTimes(1) is not pass.
What I have tried:
I have tried both expect I wrap it inside a waitFor() like this:
// request permission
await waitFor(() => expect(ImagePicker.requestMediaLibraryPermissionsAsync).toBeCalledTimes(1))
// choose from library, this line never called.
await waitFor(() => expect(ImagePicker.launchImageLibraryAsync).toBeCalledTimes(1))
But the error still the same which is launchImageLibraryAsync() never get called.
Question:
What causing
launchImageLibraryAsync()not get called? And how to solve this.I thought of I need to wait for
requestMediaLibraryPermissionsAsyncto finish resolved, then onlylaunchImageLibraryAsync()will get called. But how can I do that? As you can see I already wrap it withwaitFor(), but the error still persist.