Шутка - Утверждение о вложенности обещаний никогда не возвращается - PullRequest
0 голосов
/ 07 мая 2018

В настоящее время я экспериментирую с идеей использования Jest для живого тестирования API. Может быть, есть лучший инструмент, но я думаю, что это для другого обсуждения. Я столкнулся с проблемой, когда Jest возвращает ошибку: Expected one assertion to be called but received zero assertion calls., когда утверждение находится внутри второго обещания. Я думаю, что Jest поддержит вложение обещаний, но, похоже, оно не работает так, как ожидалось. Похоже, утверждение не возвращается. Этот синтаксис отлично работает с одним обещанием.

Я использую Jest V22.4.3 и Node V8.9.4.

новый-ticket.test.js

const call = require('../resources/call');

test('Create a new, valid ticket.', () => {
    expect.assertions(1);

    return call.makePostRequest(~login-url~, {
        'username': 'xxxxx',
        'password': 'xxxxx',
        'version': 'xxxxx'
    }).then((response) => {
        call.makePostRequest(~ticket-url~, {
            'inInvType': 1,
            'inRetailOrClearance': 'R',
            'inAction': 'L',
            'inToken': response.token
        }).then((response) => {
            expect(response.retVal).toBe('0');
        });
    });
});

call.js

const https = require('https');

function makePostRequest(subURL, payload) {
    let options,
        request,
        body;

    // Convert our payload to JSON string.
    payload = JSON.stringify(payload);

    // Build our request options configuration.
    options = {
        hostname: ~base-url~,
        port: 8443,
        "rejectUnauthorized": false,
        path: subURL,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': '*/*'
        },
        observe: 'body',
        responseType: 'json',
        reportProgress: true,
        withCredentials: false
    };

    body = '';

    return new Promise((resolve) => {
        request = https.request(options, (response) => {

            // Collect our response data as it streams in.
            response.on('data', (data) => {
                body += data;
            });

            // Once ended, resolve with data.
            response.on('end', () => {
                body = JSON.parse(body);
                resolve(body);
            });
        });

        request.on('error', (err) => {
            resolve(err)
        });

        request.write(payload);
        request.end();
    });
}

module.exports.makePostRequest = makePostRequest;

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

Как тест узнает, когда ваш тестовый пример выполнен?

Вернуть обещание в вашем тестовом примере - правильная идея, но цепочка вашего обещания прерывается, когда вы запрашиваете URL билета.Попробуйте вернуть Обещание из этого запроса.

const call = require('../resources/call');

test('Create a new, valid ticket.', () => {
    expect.assertions(1);

// => Returning the promise is the right idea but ...
    return call.makePostRequest(~login-url~, {
        'username': 'xxxxx',
        'password': 'xxxxx',
        'version': 'xxxxx'
    }).then((response) =>
// ... the inner block doesn't return anything.
// Without a Promise to signal there's async code running,
// Jest won't run this block. Try returning this call (delete the {})
        call.makePostRequest(~ticket-url~, {
            'inInvType': 1,
            'inRetailOrClearance': 'R',
            'inAction': 'L',
            'inToken': response.token
        }).then((response) => {
            expect(response.retVal).toBe('0');
        });
    );
});

Если вам нравится асинхронное / ожидание, вы также можете поиграть с ним:

const call = require('../resources/call');

test('Create a new, valid ticket.', async () => {
    expect.assertions(1);

    let response = await call.makePostRequest(~login-url~, {
        'username': 'xxxxx',
        'password': 'xxxxx',
        'version': 'xxxxx',
    });

    response = await call.makePostRequest(~ticket-url~, {
        'inInvType': 1,
        'inRetailOrClearance': 'R',
        'inAction': 'L',
        'inToken': response.token,
    });

    expect(response.retVal).toBe('0');
});
0 голосов
/ 07 мая 2018

Похоже, что моя проблема была совершенно не связана с Jest, но я опубликую ее здесь на тот случай, если у кого-то еще возникнет подобная проблема.При выполнении вызовов API мои скрипты Node направляются на балансировщик нагрузки.В своем коде я сначала звоню, чтобы запросить новый токен.Затем я использую этот токен во втором вызове, чтобы создать новую транзакцию на сервере.Проблема заключалась в том, что на одном из наших серверов часы были настроены на несколько секунд иначе, чем на другом.Итак, я получал токен от «более быстрого» сервера, а затем иногда балансировщик нагрузки направлял меня на «более медленный» сервер.Когда я пытался использовать токен на «медленном» сервере, он считался недействительным, поскольку он был выпущен в будущем.

Чтобы устранить эту проблему, я включил NTP в этом учебном пособии: https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-ubuntu-16-04

0 голосов
/ 07 мая 2018

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

Поскольку вы используете довольно современную версию Jest и Node, вы можете использовать ключевые слова async / await, так как это прояснит, что на самом деле происходит, и избавит вас от беспорядка обратного вызова, с которым вы связаны чтобы попасть в себя.

Нечто подобное должно сработать;

it('Create a new, valid ticket.', async () => {
    const res = await call.makePostRequest(~login-url~, {
        'username': 'xxxxx',
        'password': 'xxxxx',
        'version': 'xxxxx'
    });

    const response = await call.makePostRequest(~ticket-url~, {
        'inInvType': 1,
        'inRetailOrClearance': 'R',
        'inAction': 'L',
        'inToken': res.token
    });

    expect(response.retVal).toBe('0');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...