Home > Enterprise >  Jest won´t complete my async function for my api call function
Jest won´t complete my async function for my api call function

Time:05-13

I´m working on a small app that uses an API. I want to make a test to see that the function works as intended. The function works, but in the test, the function will not complete and therefore fail. I´ve looked here on stack overflow and on youtube for hours and I still do not get it to work.

Here is my test case:

import * as API from './geonames';


test('Get the country code from sweden', async () => {
    
    
    return API.getCountryCode("Sweden").then(res => console.log(res));
    
    
}, 5000);

And here is my function:


export async function getCountryCode(country: string): Promise<any> {
    // uses the ninja API to get the country code
    var url = 'https://api.api-ninjas.com/v1/country?name='   country;
    try {
        console.log("Before res"); // this runs in my test
        let res = await fetch(url, { headers: {'X-Api-Key': API_NINJA_KEY}});
        console.log("After res"); // this does not run in my test
        let data = await res.json();
        console.log("After data")
        var countryCode = data[0]['iso2'];
    
        return countryCode
    } catch (e) {

    }
}

CodePudding user response:

I think the problem is the fetch() function. On Clientside it exists (in browser) but on nodejs it does not exist. Since you added a try/catch block the error is silently omitted.

First of, log the error!!, It is really dangerous to NOT log an error. Usually prefer to log it anywhere as long as you are in development environment.

export async function getCountryCode(country: string): Promise<any> {
    // uses the ninja API to get the country code
    var url = 'https://api.api-ninjas.com/v1/country?name='   country;
    try {
        console.log("Before res"); // this runs in my test
        let res = await fetch(url, { headers: {'X-Api-Key': API_NINJA_KEY}});
        console.log("After res"); // this does not run in my test
        let data = await res.json();
        console.log("After data")
        var countryCode = data[0]['iso2'];
    
        return countryCode
    } catch (e) {
        /// Always log or throw an error, never silent!!
        console.error('GetCountryCode() failed..', e)
    }
}

solution

You need to use some other library for fetching in the tests. So for making the getCountryCode() working in browser and code ideally create a helper function for getting correct request. I suggest even to create a general request function which you use always.

For example:

// Use any module on serverside you want. I suggest axios
import axios from 'axios'

// Always run all http requests over this function
// The function decides which implementation to use.
const get_requester = () => {
    // if fetch present, return it!
    if (window && typeof fetch === 'function') {
        return fetch
    }

    return axios


}

const requestApi = (url: string, opts: Object) => {
    const request = get_requester()

    // do request.. You may need to modify a little
    request(url, opts)

}

And then in getCountryCode() use it like:


// ... import request
export async function getCountryCode(country: string): Promise<any> {
    // uses the ninja API to get the country code
    var url = 'https://api.api-ninjas.com/v1/country?name='   country;
    try {
        console.log("Before res"); // this runs in my test
        // make use of request api
        let res = await requestApi(url, { 
            headers: {'X-Api-Key': API_NINJA_KEY}, 
             method: 'GET' 
        });
        console.log("After res"); // this does not run in my test
        let data = await res.json();
        console.log("After data")
        var countryCode = data[0]['iso2'];
    
        return countryCode
    } catch (e) {

    }
}

  • Related