Вложенный Asyn c await внутри таймера - не возвращает желаемое значение - PullRequest
2 голосов
/ 18 июня 2020

Мне нужно проверить ответ конечных точек с помощью тестов Mocha и chai. Ниже приведен код для того же:

async function getData (userId) {
        let response;
        let interval = setInterval(async () => {
            response = await superagent.get("localhost:3000/user/details/").query({'user': userId}).type('application/json');
            if (response.body["status"] == 'DONE') {
                clearInterval(interval);
                response = await superagent.get("localhost:3000/user/details/get").type('application/json');
            }
        }, 10000);

    return response;    

}

Код теста:

it('User Get Data', async function () {
        return getData(userId,).then(function (res) {
            expect(res).to.exist;
            expect(res.status).to.equal(200);
            expect(res.body).to.contain('operation');
            expect(res.body["userDetails"]).to.exist;


        });

Я всегда получаю ответ как нулевой, и мой тест не проходит. Пожалуйста, дайте мне знать, где я ошибаюсь с этим кодом.

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Не используйте setInterval с обещаниями и никогда не передавайте async function в качестве обратного вызова, когда возвращенное обещание игнорируется. В вашем случае используйте вместо этого al oop:

async function getData (userId) {
    let response;
    do {
        await delay(10000);
        response = await superagent.get("localhost:3000/user/details/").query({'user': userId}).type('application/json');
    } while(response.body["status"] != 'DONE');

    return superagent.get("localhost:3000/user/details/get").type('application/json');
}

с

function delay(t) {
    return new Promise(resolve => setTimeout(resolve, t));
}
0 голосов
/ 18 июня 2020

Отредактировано, чтобы избавиться от while l oop:

Вы можете переписать getData на async/await и заключить interval в обещание. Как только первый ответ будет в порядке, очистите интервал, разрешите обещание и выполните второй вызов.

В модульном тесте просто ожидайте эту функцию, а затем проверьте детали ответа. Обратите внимание, что вы можете увеличить время ожидания мокко по умолчанию для теста, поскольку это может занять некоторое время. Что-то вроде:

async function getData(userId) {

    const firstResponsePromise = new Promise(resolve => {
            const interval = setInterval(async() => {
                    const response = await superagent.get('localhost:3000/user/details/').query({
                            'user': userId
                        }).type('application/json');
                    if (response.body['status'] == 'DONE') {
                        clearInterval(interval);
                        resolve();
                    }

                }, 10000)
        });

    await firstResponsePromise;
    return superagent.get('localhost:3000/user/details/get').type('application/json');

}

// unit test

it('User Get Data', async function () {
    const res = await getData(userId);
    expect(res).to.exist;
    expect(res.status).to.equal(200);
    expect(res.body).to.contain('operation');
    expect(res.body["userDetails"]).to.exist;

});
...