Jest 不会为我的 api 调用函数完成我的异步函数

Jest won´t complete my async function for my api call function

我正在开发一个使用 API 的小应用程序。我想进行测试以查看该功能是否按预期工作。该功能有效,但在测试中,该功能将无法完成并因此失败。我在堆栈溢出和 youtube 上看了几个小时,但我仍然无法正常工作。

这是我的测试用例:

import * as API from './geonames';


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

这是我的功能:


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) {

    }
}

我认为问题出在 fetch() 函数上。在客户端它存在(在浏览器中)但在 nodejs 它不存在。由于您添加了一个 try/catch 块,错误被 悄悄地 忽略了。

首先,记录错误!!记录错误真的很危险。只要你在开发环境中,通常更喜欢在任何地方记录它。

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)
    }
}

解决方案

您需要使用其他一些库来获取测试。因此,为了使 getCountryCode() 在浏览器和代码中工作,理想情况下创建一个辅助函数来获取正确的请求。我什至建议创建一个你经常使用的通用请求函数。

例如:

// 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)

}

然后在 getCountryCode() 中使用它:


// ... 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) {

    }
}