Chai ‘expect’ не выполняется внутри обратного вызова

#javascript #node.js #unit-testing #ramda.js

#javascript #node.js #модульное тестирование #ramda.js

Вопрос:

Я пишу модульные тесты для своей функции, которая извлекает информацию из некоторого REST API. Я использую ramda Future type (source).
Следующий тест работает странно:

   it('should return Maybe of Nothing', done => {

    let response = {
      status: 200,
      json: () => {
        return {
          results: []
        }
      }
    }

    let fakeFetch = {
      fetch: () => {
        return new Promise((resolve, reject) => {
          resolve(response)
        })
      }
    }

    //                 String -> Future Error Maybe
    let result = Utils.fetchGiantBomb(faker.random.word(), fakeFetch.fetch); 

    result.fork(err => {
      assert.fail(err, 'expected to return Maybe of Nothing'); 
      done();
    }, data => {
      expect(Maybe.isJust(data)).to.be.true;
      done();
    })

  })
 

data должно быть типа Maybe.Nothing . Если я ожидаю Maybe.isNothing , что тест пройдет, но я хочу посмотреть, что произойдет, когда тест завершится неудачей, поэтому я установил для него значение Maybe.isJust , которое возвращает false . Посмотрев на это некоторое время, я заметил, что при expect сбое он переходит к обработке ошибок ( err обратному вызову), которая затем просто прекращает выполнение любого утверждения (что приводит к таймауту 2000 мс).

В Future источниках я видел, что при сбое успешного обратного вызова выполняется обратный вызов сбоя. Как я могу выполнить этот тест, чтобы он отображал, что данные не соответствуют моим ожиданиям?

Ответ №1:

Я думаю, проблема в том, что, когда ваш вызов REST завершается неудачно, done() он никогда не вызывается.

Не уверен, есть ли expect метод .catch при сбое, но вы можете попробовать добавить

 .catch(done);
 

в конце вашей ожидаемой функции.

Надеюсь, это поможет.

Ответ №2:

future.fork(errorHandler, successHandler) В настоящее время вызов гарантирует, что любые исключения, генерируемые в successHandler , будут распространяться на errorHandler .

Один из способов обойти это (хотя, возможно, не идеальный, поскольку он недокументирован) — вызвать future._fork(errorHandler, successHandler) , а не future.fork там, где ошибки, вызванные в successHandler , не будут зафиксированы.

В качестве альтернативы, ряд тестовых фреймворков поддерживают передачу ошибки в done обратный вызов, например:

 result.fork(err => {
  done('Expected to return Maybe of Nothing: '   err);
}, data => {
  expect(Maybe.isJust(data)).to.be.true;
  done();
})
 

Ответ №3:

Я думаю, что Ramda не должен перехватывать исключение там. Но я не знаю, что они пытаются сделать.

Похоже, вы используете Mocha. Возможно, было бы неплохо сначала преобразовать ваше будущее в обещание, а затем выполнить обещание. ie:

 const futureToPromise = future => {
  return new Promise((resolve, reject) => future.fork(reject, resolve))
}

it('should return Maybe of Nothing', () => {

  let response = {
    status: 200,
    json: () => {
      return {
        results: []
      }
    }
  }

  let fakeFetch = {
    fetch: () => {
      return new Promise((resolve, reject) => {
        resolve(response)
      })
    }
   }

  // String -> Future Error Maybe
  let result = Utils.fetchGiantBomb(faker.random.word(), fakeFetch.fetch); 
  // return it because Mocha can handle this
  return futureToPromise(result).then(data => {
    expect(Maybe.isJust(data)).to.be.true;
  }, () => {
    // fail
    assert.fail(err, 'expected to return Maybe of Nothing'); 
  })
})