4

I have replicated an example to understand the testing of Mock-async-storage for reactjs. Any suggestions for a different approach of testing are welcome. I tried to replicate the use case from this stack overflow page : How to test Async Storage with Jest? but I couldn't figure out how that would fit for my sample case. So I tried the below npm module https://github.com/devmetal/mock-async-storage, but that didn't help either.

Code written in Example.test.js

import  AsyncStorage  from '@react-native-community/async-storage';

beforeEach(() => {
    AsyncStorage.clear();
    // console.log(`After the data is being reset :`)
    // console.log(AsyncStorage)
});

it('can read asyncstorage', async () => {

    await AsyncStorage.setItem('username', 'testUser')
    let username = await AsyncStorage.getItem('username')
    // console.log(`After the data is being set :`)
    // console.log(AsyncStorage)
    expect(username).toBe('testUser')
});

Code in jest.config.js file :

module.exports = {
    setupFilesAfterEnv: [
      './setup-tests.js',
    ],
  };

Code in setup-tests.js

import MockAsyncStorage from 'mock-async-storage';

const mockImpl = new MockAsyncStorage();
jest.mock('@react-native-community/async-storage', () => mockImpl);

Created the mocks folder in root directory and then created @react-native-community folder in it. Then created at async-storage.js file with the following code :

export default from '@react-native-community/async-storage/jest/async-storage-mock'

I am using jest-expo for testing.

The output of the above test case is :

enter image description here

Teja Goud Kandula
  • 1,462
  • 13
  • 26
  • It's unclear what you try to achieve with Example.test.js (there's no test). `jest.mock('AsyncStorage', () => mockImpl)` fails because there's no module named `AsyncStorage`. – Estus Flask Nov 05 '20 at 11:15
  • I want to mock Asyncstorage. I am trying to implement something like a hello world project for mocking Asyncstorage. What can I do to get rid of that error. What extra lines of code should I add please. Thanks in Advance. – Teja Goud Kandula Nov 05 '20 at 11:25
  • Mock the same module you use to import it. If it's `react-native`, mock `react-native`. – Estus Flask Nov 05 '20 at 11:28
  • Imported ```AsyncStorage``` from the ```@react-native-community/async-storage```. But still the test case is throwing same error. This is a react native app. My final intention is that I should get the username property for the app from the Asynstorage mock. – Teja Goud Kandula Nov 05 '20 at 13:12
  • 1
    It's throwing the same error because you mock wrong and non-existing module. You need to mock `@react-native-community/async-storage`. Did you try that? – Estus Flask Nov 05 '20 at 13:15
  • Updated the code as per the last comment. Now I am able to read the Asyncstorage. Thanks Estus. – Teja Goud Kandula Nov 05 '20 at 16:09
  • I have one last thing to accomplish. I need to fetch the value of username from the Asyncstorage, i.e. getItem('username') value. In order for getItem('username') to work I need to setItem('username). Can you let me know how to do implement that. Instead of username I used foo for now. I have updated the code and the error message. Thanks in advance. – Teja Goud Kandula Nov 05 '20 at 16:58
  • Likely `await AsyncStorage.setItem('foo', ...); let foo = await AsyncStorage.getItem('foo')`? Actually `getItem` should occur inside the code you test because by calling it directly you test the line you've just written. I'm not sure if this is real or pseudocode in the question but the use of `this` is incorrect here, it doesn't refer to a context that would make sense. Btw you may want to call `clear` in `beforeEach` in setup-tests, tests shouldn't affect each other through a storage. – Estus Flask Nov 05 '20 at 17:44
  • I have updated the code as per your last comment. Now the test case is working as expected. Many Thanks, @estus-flask. You have helped me in saving a lot of time. – Teja Goud Kandula Nov 06 '20 at 05:15

1 Answers1

3

Detailed Solution for the above:

Install the module using the command : Run this command from the root directory of the project.

npm install --save mock-async-storage

In the project root directory create __mocks__\@react-native-community folder. Inside that create a file async-storage.js. Code in async-storage.js

export default from '@react-native-community/async-storage/jest/async-storage-mock'

Inside package.json configure the jest as follows:

"jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns" : ["/node_modules/@react-native-community/async-storage/(?!(lib))"]
  },

Here I am using jest-expo for testing. If you are using jest then the preset value will be jest not jest-expo.

In the project root directory create a file called jest.config.js Configuration inside the jest.config.js file:

module.exports = {
    setupFilesAfterEnv: [
      './setup-tests.js',
    ],
  };

In the project root directory create a file called setup-tests.js. Code in this file is :

import MockAsyncStorage from 'mock-async-storage';

const mockImpl = new MockAsyncStorage();
jest.mock('@react-native-community/async-storage', () => mockImpl);

In the project root directory create the test file. Here I am calling it Example.test.js.

import  AsyncStorage  from '@react-native-community/async-storage';

beforeEach(() => {
    AsyncStorage.clear();
    // console.log(`After the data is being reset :`)
    // console.log(AsyncStorage)
});

it('can read asyncstorage', async () => {

    await AsyncStorage.setItem('username', 'testUser')
    let usernameValue = await AsyncStorage.getItem('username')
    // console.log(`After the data is being set :`)
    // console.log(AsyncStorage)
    expect(usernameValue).toBe('testUser')
});

Here setting the value of username to testUser using AsyncStorage.setItem. Then fetching the value using getItem function. The test case is to compare whether the usernameValue is equal to testUser. If yes then the test case passes else the test case will fail.

Using beforeEach so that every time a test case is being run Asyncstorage is being cleared and is empty. If needed one can check what is present in Asyncstorage using console.log

Run the command yarn test to run the tests. The output is:

enter image description here

Teja Goud Kandula
  • 1,462
  • 13
  • 26