Как смоделировать необходимые файлы в Node.js? - PullRequest
0 голосов
/ 08 января 2019

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

const makeRequestStructure = require('./modules/makeRequestStructure.js').makeRequestStructure
const normalizeFinalResponse = require('./modules/normalizeFinalResponse.js').normalizeFinalResponse
const doARequest = require('./modules/doARequest.js').doARequest

exports.addPost = (event) => {
  const requestStructure = makeRequestStructure('POST', '/posts')

  const requestPostData = {
    title: event.body.title,
    content: event.body.content
  }

  return doARequest(requestStructure, requestPostData).then((res) => {
    const finalResponse = normalizeFinalResponse(200, res)
    return finalResponse
  }).catch((err) => {
    const finalResponse = normalizeFinalResponse(400, err)
    return finalResponse
  })
}

У меня есть следующий тестовый файл:

const mock = require('mock-require')
const sinon = require('sinon')
const expect = require('chai').expect

const addPost = require('../addPost.js')

describe('the addPost API call', () => {
  beforeEach(() => {
    mock('../modules/doARequest', { doARequest: function() {
      return Promise.resolve({})
    }})
  });
  it('Returns with a statusCode of 200', () => {
    const event = { body: { title: 'Lorem ipsum', content: 'Lorem ipsum dolor sit amet' } }
    const expectedReturn = { id: 20000000000000 }
    return addPost.addPost(event).then((res) => {
      expect(res.body.message).to.eql(expectedReturn)
    })
  });
})

Этот тест выполняет фактический вызов https://jsonplaceholder.typicode.com/posts и возвращает { id: 101 }. Однако я хочу, чтобы это вернуло { id: 20000000000000 }. Я попытался смоделировать запрос, используя Nock . Однако имя хоста определено в файле .env и может отличаться в зависимости от сервера, на котором выполняется скрипт.

Файл doARequest.js выглядит следующим образом:

const https = require('https')

module.exports.doARequest = function (params, postData) {
  return new Promise((resolve, reject) => {
    const req = https.request(params, (res) => {
      let body = []
      res.on('data', (chunk) => {
        body.push(chunk)
      })
      res.on('end', () => {
        try {
          body = JSON.parse(Buffer.concat(body).toString())
        } catch (e) {
          reject(e)
        }
        resolve(body)
      })
    })
    req.on('error', (err) => {
      reject(err)
    })
    if (postData) {
      req.write(JSON.stringify(postData))
    }
    req.end()
  })
}

Что я здесь не так делаю? Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

В качестве альтернативы решению estus с повторным запросом модуля вы можете использовать «внедрение зависимостей».

Проблема в том, что вы напрямую зависите от doARequest.js -модуля в addPost.js, что затрудняет его поведение. Вот где внедрение зависимостей оказывается полезным, поскольку вы можете просто пропустить поддельный модуль doARequest в своем модульном тесте:

// addPost.js
exports.addPost = (event, doARequest) => {
    const requestStructure = makeRequestStructure('POST', '/posts')

    const requestPostData = {
        title: event.body.title,
        content: event.body.content
    }

    return doARequest(requestStructure, requestPostData).then((res) => {
        const finalResponse = normalizeFinalResponse(200, res)
        return finalResponse
    }).catch((err) => {
        const finalResponse = normalizeFinalResponse(400, err)
        return finalResponse
    })
}

// addPost.test.js
describe('the addPost API call', () => {        
    it('Returns with a statusCode of 200', () => {
        const mockedDoARequest = () => Promise.resolve({ "whateverResponseYouLike": "12345" });
        const event = { body: { title: 'Lorem ipsum', content: 'Lorem ipsum dolor sit amet' } }
        const expectedReturn = { id: 20000000000000 }
        return addPost.addPost(event, mockedDoARequest).then((res) => {
            expect(res.body.message).to.eql(expectedReturn)
        })
    });
})

Везде, где бы вы не передавали настоящий модуль, т. Е.

const doARequest = require('./modules/doARequest.js').doARequest
...
return addPost.addPost(event, doARequest).then(...)
0 голосов
/ 08 января 2019

Модули CommonJS генерируют одноэлементные объекты экспорта. Как только модуль импортирован, он не оценивается. mock(...) ни на что не влияет, потому что оригинальный модуль doARequest был оценен при импорте addPost.

mock-require предоставляет способ переоценки модулей . addPost не следует импортировать вверху тестового файла. Вместо этого его следует импортировать в тест, в котором он используется:

const addPost = mock.reRequire('../addPost.js');
...