Зачем нам нужен nock для модульного теста HTTP-запроса?

Ниже приведен пример кода из избыточного документа.

describe('async actions', () => {
  afterEach(() => {
    nock.cleanAll()
  })

  it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', () => {
    nock('http://example.com/')
      .get('/todos')
      .reply(200, { body: { todos: ['do something'] }})

    const expectedActions = [
      { type: types.FETCH_TODOS_REQUEST },
      { type: types.FETCH_TODOS_SUCCESS, body: { todos: ['do something']  } }
    ]

    const store = mockStore({ todos: [] })

    return store.dispatch(actions.fetchTodos())
      .then(() => { // return of async actions
        expect(store.getActions()).toEqual(expectedActions)
      })
  })
})

Почему мы должны использовать nock для этого модульного теста? Я не видел, чтобы в этом примере кода использовались данные из nock.


person Dreams    schedule 31.03.2017    source источник


Ответы (2)


Nock используется для имитации http-запросов — если вы имитируете http-запрос, это означает, что ваш код не выполняет настоящие http-запросы к серверу.

Nock (и любая другая библиотека имитации http) переопределяет собственные методы http-запросов, поэтому настоящие http-запросы никогда не будут отправлены. У этого есть много преимуществ - например, вам не нужно ждать фактического ответа сервера, потому что имитированный запрос возвращает ответ в кратчайшие сроки, и, конечно же, ваш тест не зависит от сервера. Вы можете сосредоточиться на тестировании кода приложения и не беспокоиться о сервере - даже если сервер не работает, вы можете запустить тест.

Вам не нужно явно использовать данные, возвращаемые фиктивным запросом, если вам не нужно их тестировать - основная причина использования nock в вашем примере кода заключается в том, чтобы предотвратить фактический HTTP-запрос к серверу, который обычно отправлялся бы действием FETCH_TODOS_REQUEST. Кроме того, даже если смоделированные данные ответа явно не используются в тестах, они, вероятно, используются в коде приложения (вероятно, FETCH_TODOS_SUCCESS действие ожидает, что массив todos будет возвращен), поэтому вам нужно смоделировать данные ответа, чтобы ваше приложение получило ожидаемые данные.
Если бы nock не использовался, тест занял бы гораздо больше времени, потому что был бы отправлен реальный HTTP-запрос на сервер.

person Bartek Fryzowicz    schedule 31.03.2017
comment
Большое спасибо. Если я использую запрос Ajax для вызова моего API, перехватит ли его nock? или нет, только перехватывать вызов? - person Dreams; 31.03.2017
comment
Добро пожаловать. nock работает только в окружении узла, а не в окружении браузера. В примерах документа Redux используется Jest (который запускает тест в node env) в качестве средства запуска теста и isomorphic-fetch для создания http-запроса, который также поддерживает node env, поэтому nock работает, но я боюсь, что если вы попытаетесь использовать API браузера для вызова AJAX, он не будет work - nock не переопределяет методы API браузера. Пожалуйста, проверьте также этот ответ SO: stackoverflow.com/a/40270833/7518718 - person Bartek Fryzowicz; 31.03.2017

Главным образом потому, что в этом тесте нас интересуют действия, производимые actions.fetchTodos(). Это действие вызовет конечную точку /todos, возвращая действия с некоторыми данными. Поскольку нас интересуют только данные, содержащиеся в действиях, мы просто издеваемся над ними.

Nock внутренне перехватывает настоящий вызов fetch для /todos и возвращает успешный код 200, что позволяет продолжить работу хранилища избыточности.

Данные, которые вы ищете,

{ todos: ['do something']  }

Это высмеивается, а также ожидается позже

person Ignacio    schedule 31.03.2017