Harkirat Saluja

@salujaharkirat

Testing chained promises with jest in react-native using mock-data

I was developing login screen for my react native application with google-sign-in as option. The logic involved nested promises and was built using chain promises.

Developing the code was easy but when I started to write unit test cases for this logic I was really mind-blown. I could not find any good documentation for handling this scenarios though few examples helped along the way

The documentation provided by jest team for async code works well for single promises. The code structure can be found at https://github.com/facebook/jest/tree/master/examples/async .

After reading the documentation I think there are few things which are missing:-

  1. It says that __mocks__ folder should be present inside the same folder as the file to be tested.
  2. It asks to relatively import the function which is to be tested into the test folder.

This works fine with relative imports but my code was structured to use absolute imports by making changes in the .babelrc file.

Following is my folder structure :-

I like having tests segregated and so I created a separate __tests__ folder.

Now, if I follow the requirements of jest as mentioned above I have to create a folder called __mocks__ inside a particular screen.

In order to make this work now I have to import from __mocks__ relatively into __tests__/tests/screens/Auth. I tried that and it worked fine. But as my entire project was using absolute imports I did not want to add relative imports specifically for this purpose.

I made few small tweaks in order to make this work using absolute imports.

So lets get started with that.

Lets check out the Auth.container.js code first to see how business logic is implemented.

On button onPress I call the function onPress in this component which does following:-

  1. Uses react-native-google-sign-in to authenticate with google and returns email, idToken and status .

If you I have added TEST_authorizeGoogle in this file about which I will talk when come to the test code . For now just checkout authorizeUser function.

2. Calls my backend with the generated email and idToken to generate a new accessToken for the user and log him(or her) in.

Once more ignore TEST_setLoginGoogle for now.

Now lets take a look at the actually test case.

First I have imported the mocks from the mocks folder which I created locally.

Next, I override the function authorizeGoogle using TEST_setAuthorizeGoogle and loginGoogle using TEST_setLoginGoogle . This is done because in ES6 named exports are always constants. Check out here for more info.

First I test if the second promise is called with the result of first promise or not at line 54 of the above code.

Second, I test if final data is same as the mock data returned by my server which is done at line 55.

In this way I was able to segregate test folders and use absolute imports to test my component for chained promises.

Feedbacks are welcome!! Cheers!!

More by Harkirat Saluja

Topics of interest

More Related Stories