тестирование множественного http-запроса с использованием mocha - PullRequest
0 голосов
/ 11 ноября 2019

Я пытался решить эту проблему в течение нескольких дней;создайте тест для этого случая, используя mocha:

app.post('/approval', function(req, response){
request.post('https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state + '?private_token=blabla', function (error, resp, body) {
    if (resp.statusCode == 201) {
                //do something
            } else {
                response.send("failed"), response.end();
            }
        });  
    } else {
        response.send("failed"), response.end();
    }
});

});

Я пробовал несколько способов: использовать supertest для проверки '/ Approval' и использовать nock для проверки сообщенияпросьба к git api. Но всегда включается «statusCode» не определено. Я думаю, это потому, что запрос git api в index.js не находится внутри определенной функции (?), Поэтому я не могу реализовать что-то вроде этого: https://codeburst.io/testing-mocking-http-requests-with-nock-480e3f164851 или https://scotch.io/tutorials/nodejs-tests-mocking-http-requests

    const nockingGit = () => {
    nock('https://git.ecommchannel.com/api/v4/users')
        .post('/1/yes', 'private_token=blabla')
        .reply(201, { "statusCode": 201 });
};

it('approval', (done) => {
let req = {
    content: {
        id: 1,
        state: 'yes'
    },
    _id: 1
}
request(_import.app)
    .post('/approval')
    .send(req)
    .expect(200)
    .expect('Content-Type', /html/)
    .end(function (err, res) {
        if (!err) {
            nockingGit();  
        } else {
            done(err);
        }
    });
done();

})

Затем я попытался использовать супертест в качестве обещания

    it('approve-block-using-promise', () => {
       return promise(_import.app)
        .post('/approval')
        .send(req = {
            content: {
                id: 1,
                state: 'yes'
            },
            _id: 1
        })
        .expect(200)
        .then(function(res){
            return promise(_import.app)
            .post("https://git.ecommchannel.com/api/v4/users/")
            .send('1/yes', 'private_token=blabla')
            .expect(201);
        })
})

Но выдает ошибку: ECONNEREFUSED: Соединение отказано. Я не нашел никакого решения для устранения ошибки. В некоторых источниках сказано, что для этого нужно сделать done () .. но выдается еще одно сообщение об ошибке: «убедитесь, что« done () »вызвано»>. <</p>

Итак, я нашел другой способ, используя async (https://code -examples.net / ru / q / 141ce32 )

    it('should respond to only certain methods', function(done) {
    async.series([
        function(cb) { request(_import.app).post('/approval')
        .send(req = {
            content: {
                id: 1,
                state: 'yes'
            },
            _id: 1
        })
        .expect(200, cb); },
        function(cb) { request(_import.app).post('/https://git.ecommchannel.com/api/v4/users/').send('1/yes', 'private_token=blabla').expect(201, cb); },
    ], done);
});

и выдает эту ошибку: ожидается 201 "Создано", получено 404 "Не найдено". Хорошо, еслиЯ открываю https://git.ecommchannel.com/api/v4/users/1/yes?private_token=blabla в браузере, он возвращает 404. Но я ожидаю, что я ввел ответ на 201 от модульного теста, так что каков бы ни был фактический ответ, statusCode предполагает 201, верно? Но тогда, поскольку он выдает эту ошибку, означает ли это, что модульный тест действительно отправляет запрос в API? Пожалуйста, помогите мне решить эту проблему: как проверить первый код, которым я поделился. Я действительно новичок в модульном тесте.

1 Ответ

0 голосов
/ 11 ноября 2019

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

Прежде всего, ваш звонок на git.ecommchannelв контроллере это POST без тела. Хотя это не вызывает ошибок, которые вы видите, и технически не является неправильным, это странно. Поэтому вам следует дважды проверить, какие данные вы должны отправлять.

Далее, я предполагаю, что это была проблема копирования / вставки при создании вопроса, но обратный вызов для запроса в вашем контроллере недействительный JS. Квадратные скобки не совпадают, и отправка "сбой" происходит дважды.

У вашей настройки Nock было две проблемы. Сначала аргумент nock должен иметь только источник, но не путь. Так что /api/v4/users нужно было перенести в первый аргумент метода post. Другая проблема была со вторым аргументом, переданным post, который является необязательным соответствием тела POST. Как указано выше, вы в настоящее время не отправляете тело, поэтому Nock всегда не сможет найти и заменить этот запрос. В приведенном ниже примере private_token был перемещен для сопоставления со строкой запроса, так как то, что было показано как происходящее.

Вызов nockingGit происходил слишком поздно. Nock необходимо зарегистрировать макет, прежде чем использовать Supertest для вызова приложения Express. Он вызывается в методе end, к тому времени уже слишком поздно.

Тест с пометкой approve-block-using-promise имеет проблему со вторым вызовом приложения. Он вызывает post через Supertest в приложении Express, однако первым аргументом этого метода post является путь запроса, который вы делаете в свое приложение. Это не имеет никакого отношения к звонку на git.ecommchannel. Так что в этом случае ваше приложение Express должно было вернуть 404. Not Found.

const express = require('express')
const nock = require('nock')
const request = require('request')
const supertest = require('supertest')

const app = express()
app.use(express.json())

app.post('/approval', function(req, response) {
  const url = 'https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state
  request.post({
      url,
      qs: {private_token: 'blabla'}
      // body: {} // no body?
    },
    function(error, resp, body) {
      if (error) {
        response.status(500).json({message: error.message})
      } else if (resp.statusCode === 201) {
        response.status(200).send("OK")
      } else {
        response.status(500).send("failed").end();
      }
    });
});

const nockingGit = () => {
  nock('https://git.ecommchannel.com')
    .post('/api/v4/users/1/yes')
    .query({private_token: 'blabla'})
    .reply(201, {"data": "hello world"});
};

it('approval', (done) => {
  const reqPayload = {
    content: {
      id: 1,
      state: 'yes'
    },
    _id: 1
  }

  nockingGit();

  supertest(app)
    .post('/approval')
    .send(reqPayload)
    .expect(200)
    .expect('Content-Type', /html/)
    .end(function(err) {
      done(err);
    })
})
...