Как смоделировать вызов двух топоров ios в одной конечной точке - PullRequest
0 голосов
/ 06 марта 2020

Пример:

В моем тесте мне нужно смоделировать два вызова на внешний apis. Я не могу издеваться над вторым звонком. С библиотекой 'ax ios -mock-adapter' и ava я мог только издеваться над первым вызовом.

const read = async (req, res) => {
  try {
    const responseOne = await axios({
      method: 'get',
      url: 'https://api.example.com/search/repositories',
      params: {
        q: 'example',
      },
    })
    const resultOne = responseOne.data
    if (resultOne) {
      let aux = []
      const itemsOne = resultOne.items.slice(0, 10)
      return Promise.all(
        itemsOne.map((p, indexOne) => {
          aux = [...aux, { id: p.id, name: p.name, arr: [] }]
          return axios({
            headers: { Authorization: `Bearer ${SECRET_KEY}` },
            method: 'get',
            url: 'https://api.example2.com/search/things',
            params: { q: p.name },
          })
            .then(responseTwo =>
              responseTwo.data.array.map(i => {
                aux[indexOne].arr.push({
                  id: i.id,
                  created_at: i.created_at,
                  text: i.text,
                })
              })
            )
            .catch(err => res.status(500).json(err))
        })
      )
        .then(() => res.json({ result: aux }))
        .catch(err => res.status(500).json(err))
    } else res.status(404).json({ message: 'Example not found' })
  } catch (err) {
    res.status(500).json(err)
  }
}

TEST

Это мой тест read.test. js , Сейчас я имею дело с библиотеками 'ava' и 'ax ios -mock-adapter'. Но второй вызов топора ios не работает с макетом.

import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
import test from 'ava'
import read from '../read'

var mock = new MockAdapter(axios)


test('GET - /examples', async t => {
  mock
    .onGet('https://api.example.com/search/repositories, {
      params: {
        q: 'example',
      },
    })
    .reply(200, {
      total_count: 2,
      incomplete_results: false,
      items: [
        {
          id: 555,
          name: 'exampleOne',
        },
        {
          id: 666,
          name: 'exampleTwo',
        },
      ],
    })
    .onGet('https://api.example2.com/search/things', {
      params: { q: 'name' },
      headers: { Authorization: `Bearer ${SECRET_KEY}` },
    })
    .reply(200, {
      statuses: [
        {
          id: 123,
          created_at: 'Thu Feb 27 22:54:02 +0000 2020',
          text: 'Example one.',
        },
        {
          id: 456,
          created_at: 'Wed Feb 26 13:40:20 +0000 2020',
          text: 'Example Two',
        },
      ],
    })

  try {
    const res = await read()
    t.assert(res.result[0].id.test(555))
  } catch (err) {
    console.log(`ERROR::: ${err}`)
  }

1 Ответ

0 голосов
/ 08 марта 2020

Проблема с макетом второго запроса заключается в том, что вы настраиваете его для ответа, только если конечная точка запрашивается с параметрами { q: 'name' }. Если вы хотите ответить одинаковыми данными для всех запросов на https://api.example2.com/search/things, достаточно удалить атрибут params:

.onGet('https://api.example2.com/search/things', {
    headers: { Authorization: `Bearer ${SECRET_KEY}` },
})
.reply(200, {
    statuses: [
        {
            id: 123,
            created_at: 'Thu Feb 27 22:54:02 +0000 2020',
            text: 'Example one.',
        },
        {
            id: 456,
            created_at: 'Wed Feb 26 13:40:20 +0000 2020',
            text: 'Example Two',
        },
    ],
})

В вашем тесте также присутствуют другие проблемы. В поддельном ответе вы передаете данные в свойство statuses, но в своем фактическом коде вы перебираете свойство array.

Кроме того, метод read получает два параметра, req и res. Если вы не предоставите эти объекты при вызове read в своем тесте, он сломается, так как вы вызываете методы объекта res.

Самый простой способ вызвать метод - создать поддельный req и res объекты и вызов метода read с ними. Для простоты я создам макет с помощью sinon spies :

test('GET - /examples', async t => {
  mock
    .onGet('https://api.example.com/search/repositories, {
      params: {
        q: 'example',
      },
    })
    .reply(200, {
      total_count: 2,
      incomplete_results: false,
      items: [
        {
          id: 555,
          name: 'exampleOne',
        },
        {
          id: 666,
          name: 'exampleTwo',
        },
      ],
    })
    .onGet('https://api.example2.com/search/things', {
      headers: { Authorization: `Bearer ${SECRET_KEY}` },
    })
    .reply(200, {
      array: [
        {
          id: 123,
          created_at: 'Thu Feb 27 22:54:02 +0000 2020',
          text: 'Example one.',
        },
        {
          id: 456,
          created_at: 'Wed Feb 26 13:40:20 +0000 2020',
          text: 'Example Two',
        },
      ],
    })

  const res = {
    status: sinon.stub().returnsThis(),
    json: sinon.stub().returnsThis(),
  };

  try {
    await read({}, res);
    const data = res.json.firstCall.args[0];
    t.is(data.result[0].id, 555)
  } catch (err) {
    console.log(`ERROR::: ${err}`)
  }
});

Обратите внимание, что я высмеиваю объект запроса, передавая пустой объект, так как read метод не использует никаких свойств запроса.

...