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:-
- It says that
__mocks__folder should be present inside the same folder as the file to be tested.
- 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 .
Following is my folder structure :-
I like having tests segregated and so I created a separate
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:-
- Uses react-native-google-sign-in to authenticate with google and returns
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
2. Calls my backend with the generated
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
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!!