Асинхронные запросы Mocha к Node.js API

Я использую mocha для тестирования API Node.js, который я пишу. Мне нужно, чтобы mocha отправил, например, 100 HTTP-запросов одновременно, а затем получил 100 обратных вызовов, ожидающих данных ответа. И затем, после того как все 100 из этих вызовов будут выполнены, мне нужно выполнить еще одну серию из 100 HTTP-запросов.

Что я знаю о Mocha: каждый вызов бок о бок описания функции выполняется синхронно. В одном описании я запускаю 100 HTTP-запросов, используя async (это то, что мне советовали делать в большинстве ответов Stackoverflow.

Сейчас у меня проблемы с запуском этих HTTP-запросов в асинхронном режиме. Каждый it должен быть асинхронным, но это определенно не тот случай, когда ожидание данных запроса

var registeredData = {};
describe("Run first 100 HTTP requests...", function () {
    async.map(calls, function (call, callback) {
        it('call '+call.num, function(done) {
            request({
                method: 'POST',
                uri: 'http://127.0.0.1:3000/register',
                json: {
                    data: { 
                        name: call.name,
                        id: call.id
                    }
                },
            }, 
            function (err, res) {
                expect(res.body).to.exist;
                registeredData[call.num] = res.body.info;
                done();
            });
        });
        callback();
    });
});    
describe("Run next 100 HTTP requests...", function () {
    async.map(calls, function (call, callback) {
        it('call '+call.num, function(done) {
            request({
                method: 'POST',
                uri: 'http://127.0.0.1:3000/getData',
                json: {
                    data: {
                        dataFor: registeredData[call.num] 
                    }
                },
            }, 
            function (err, res) {
                expect(res.body).to.exist;
                done();
            });
        });
        callback();
    });
});

По сути, первые 100 HTTP-запросов регистрируют учетные записи, а следующие 100 извлекают информацию для каждой соответствующей учетной записи. Я не знаю, когда звонить done() и когда звонить callback() (относительно async.map). Кто-нибудь знает, что здесь делать?


person Jeremy    schedule 11.03.2016    source источник


Ответы (1)


Возможно я ошибаюсь, но я не вижу здесь смысла использовать async.map в вашем коде.

Учитывая 100 запросов, отправьте их все в одном тесте.

Если ваш тестовый пример «Отправить 100 запросов и проверить, все ли они вернутся», вы должны использовать async в своем тесте.

it("Run first 100 HTTP requests...", function (done) {

  function sendRequest(call, next){
    request({
        method: 'POST',
        uri: 'http://127.0.0.1:3000/register',
        json: {
          data: { 
            name: call.name,
            id: call.id
          }
        },
      },
      function (err, res) {
        if(err){
          next(err);
        } else {
          expect(res.body).to.exist;
          // ... more assertions here
          next();
        }
      });
  }

  async.series(calls, sendRequest, done);

});
... more tests here 

Учитывая список из 100 вызовов, протестируйте каждый отдельный вызов

Если вы хотите иметь список вызовов и it тест для каждого из них, вы можете просто создать новый it clojure для каждого вызова. mocha зарегистрирует it тесты, а затем выполнит их.

var registeredData = {};
describe("Run first 100 HTTP requests...", function () {

  function createCallTest(call){
    it('call '+call.num, function(done) {

      request({
        method: 'POST',
        uri: 'http://127.0.0.1:3000/register',
        json: {
          data: { 
            name: call.name,
            id: call.id
          }
        },
      },
      function (err, res) {
        expect(res.body).to.exist;
        registeredData[call.num] = res.body.info;
        done();
      });
    });
  }

  // generate one test for each calls entry
  calls.forEach(function(call){

    createCallTest(call);

  });
});
... more tests here 
person MarcoL    schedule 15.03.2016
comment
да, вы правы, я вынул async.map. Но эти запросы отправляются один за другим. У меня есть два терминала, один для API, а другой для мокко-тестов, отправляющих запросы, и API не получает все вызовы асинхронно. запрос блокирует каждый последующий вызов до тех пор, пока не будет возвращен предыдущий - person Jeremy; 21.03.2016
comment
Если вам нужны одновременные вызовы, я бы порекомендовал их сгруппировать: даже если вы запускаете их все вместе, обычно максимальное количество вызовов может быть открыто параллельно. Я считаю, что 100 намного выше этого предела. - person MarcoL; 21.03.2016
comment
ну, я даже не могу получить 2 одновременных вызова с этим, хотя - person Jeremy; 21.03.2016
comment
Хорошо, тогда я думаю, что ответ выше неверен, как есть. Я обновлю его. - person MarcoL; 21.03.2016
comment
Есть ли способ настроить это так, чтобы каждый запрос был it в мокко (то есть 100 it тестов)? Потому что каждый вызов будет отдельным тестом (здесь я использую 100 как произвольное число, это может быть 5, 10, 20 и т. д.). Мне нужно, чтобы каждый it был отдельным оператором печати, говорящим, что запрос был успешным. Но я не знаю, как заказать обратные вызовы - person Jeremy; 22.03.2016
comment
Вы хотите запустить 100 запросов параллельно, но каждый запрос должен быть отдельным тестом? - person MarcoL; 22.03.2016
comment
Да. Я использовал 100 для принципа. Мне нужно будет запустить, может быть, 10 или более тестов, которые очищают веб-сайты. Поскольку они очень медленные, мне нужно, чтобы они выполнялись параллельно как отдельные тесты, чтобы я мог видеть, что не так с каждым отдельным вызовом, когда несколько вызовов терпят неудачу. Если бы я собрал их все в одном it, мне бы не очень помогло решить каждую незначительную проблему со скрейпингом. - person Jeremy; 22.03.2016
comment
Мммм. it функции могут выполняться только последовательно в mocha или jasmine или любом другом средстве запуска тестов. Есть два решения, которые я могу придумать: запустить все ваши запросы в блоке before, собрать результаты, а затем последовательно протестировать возвращенные результаты. Второе решение потребует от вас изменить средство запуска тестов и использовать ava вместо mocha, которое выполняет параллельное тестирование: я бы оставил это в крайнем случае и отдал предпочтение первому. - person MarcoL; 23.03.2016