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:-
__mocks__
folder should be present inside the same folder as the file to be tested.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:-
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!!