I have two tests running with jest on react native code. One is for a component and one is for a service. Both are not using AsyncStorage but calling other classes, which do that. For simplicity I give you here the code for the Service, the class, which is called by the Service and the test for the Service.
UserService:
import request from './request'
import * as Constants from '../../utils/Constants'
function getUser() {
return request({
url: Constants.USER,
method: 'GET'
}, true)
}
function login(user) {
return request({
url: Constants.LOGIN,
method: 'POST',
data: user
}, false)
}
const UserService = {
login, getUser
};
export default UserService;
request:
import axios from 'axios';
import AsyncStorage from '@react-native-community/async-storage';
import * as Constants from './../../utils/Constants'
/**
* Request Wrapper with default success/error actions
*/
const request = async function (options, isHeader = true) {
let token = null;
let header = null;
if (isHeader) {
token = await AsyncStorage.getItem("Auth"); /// Add header
header = {
// add special header to XHR requests
'X-Requested-With': 'XMLHttpRequest',
// add authorization
'Authorization': `${JSON.parse(token).token}`
}
}
const client = axios.create({
baseURL: Constants.BASE_URL,
headers: header
});
const onSuccess = function (response) {
console.log('Request Successful!', response);
return response.data;
}
const onError = function (error) {
console.log('Request Failed:', error.config);
if (error.response) {
// Request was made but server responded with something
// other than 2xx
console.debug('Status:', error.response.status);
console.debug('Data:', error.response.data);
console.debug('Headers:', error.response.headers);
} else {
// Something else happened while setting up the request
// triggered the error
console.debug('Error Message:', error.message);
}
return Promise.reject(error.response || error.message);
}
return client(options)
.then(onSuccess)
.catch(onError);
}
export default request;
The test for UserService:
import mockAxios from 'jest-mock-axios';
import * as Constants from './../../utils/Constants'
import UserService from './UserService';
import sinon from 'sinon';
import MockStorage from './../../test/MockStorage';
const storageCache = {};
const AsyncStorage = new MockStorage(storageCache);
jest.setMock('AsyncStorage', AsyncStorage)
afterEach(() => {
mockAxios.reset();
})
describe('UserService', () => {
it('getUser should call axios get', async () => {
const expectedUrl = `${Constants.BASE_URL}${Constants.USER}`;
const user = {user:'test', password: 'test'};
const expectedCallArgs = {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
var spy = sinon.spy(AsyncStorage, "getItem");
await UserService.getUser();
expect(mockAxios.get).toHaveBeenCalledWith(expectedUrl, expectedCallArgs);
expect(spy.calledOnce).toBeTruthy();
mockAxios.mockResponse({data: user});
});
});
When running the test, I´m getting this error:
There are also steps written down to fix this issue, but none of them helped.
The expected behavior would be, that AsyncStorage is used and is not null.
Logs/Error that are relevant:
Test suite failed to run
[@RNC/AsyncStorage]: NativeModule: AsyncStorage is null.
To fix this issue try these steps:
• Run react-native link @react-native-community/async-storage in the project root.
• Rebuild and restart the app.
• Run the packager with --clearCache flag.
• If you are using CocoaPods on iOS, run pod install in the ios directory and then rebuild and re-run the app.
• If this happens while testing with Jest, check out docs how to integrate AsyncStorage with it: https://github.com/react-native-community/async-storage/blob/LEGACY/docs/Jest-integration.md
If none of these fix the issue, please open an issue on the Github repository: https://github.com/react-native-community/react-native-async-storage/issues
at Object.
at Object.
I am facing the same error in IOS also.
^also facing this, I'm not using jest. Everything appears to have linked properly, I'm running on android.
^also facing this, I'm not using jest. Everything appears to have linked properly, I'm running on android.
This issue is resolved for me, I wasn't using jest. unlink. removed package. readd, relink. Autolinking doesnt seem to work for me, RN 0.60.5
@ElliDy
You're getting this error in your tests because native module of Async Storage is not properly mocked. Checkout jest integration docs to get more details
@dsgithub2018
You need to link this library, if not using RN 0.60+.
@Krizzu
I checked the docs again and I missed the @react-native-community folder in __mocks__. So it is working now.
I will close the issue now.
For future visitors, the Jest + AsyncStorage integration moved to https://react-native-community.github.io/async-storage/docs/advanced/jest
Most helpful comment
For future visitors, the Jest + AsyncStorage integration moved to https://react-native-community.github.io/async-storage/docs/advanced/jest