jeudi 4 mars 2021

Network error only when running axios.get() in testing environment

Why is getMaxTemperature returning a number when run from node app.js but not returning a number when run using npm run test?

I've been stuck on a coding challenge and need some help. I am using axios.get() as part of an asynchronous function and the behaviour differs between running the application directly compared to the running the test suite which has been implemented in Jest.

The application is supposed to make a get request to an API and insert specific data into a string as part of a series of console.log statements.

The following code works as expected:

node app.js 

which returns the following:

Location?
oxford or heathrow ? oxford
Year? 1950
number
The max temperature for oxford in 1950 is: 22.1

In the above code, on the second line I respond 'oxford' to the 'Location?' prompt and 1950 to the 'Year? prompt. This is followed directly by 'number' which is a troubleshooting step I introduced inside getMaxTemperature() because I cannot work out why this function is not returning a number when the test suite is executed. Instead, I believe it is returning a promise in the test environment.

Here is the failure I am trying to overcome:

command:

npm run test

Response:

> weatherclient@1.0.0 test /Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test
> jest

 FAIL  tests/getMaxTemperature.test.js
  ● Console

    console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Error: Response for preflight has invalid HTTP status code 403
          at Object.dispatchError (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:54:19)
          at EventEmitter.<anonymous> (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
          at EventEmitter.emit (events.js:327:22)
          at Request.<anonymous> (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:357:16)
          at Request.emit (events.js:315:20)
          at Request.onRequestResponse (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/request/request.js:1059:10)
          at ClientRequest.emit (events.js:315:20)
          at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:596:27)
          at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
          at TLSSocket.socketOnData (_http_client.js:469:22) undefined

  ● getMaxTemperature › Successfully gets the max Temperature for oxford 2018

    Network Error

      at createError (node_modules/axios/lib/core/createError.js:16:15)
      at XMLHttpRequest.handleError (node_modules/axios/lib/adapters/xhr.js:84:14)
      at XMLHttpRequest.<anonymous> (node_modules/jsdom/lib/jsdom/living/helpers/create-event-accessor.js:33:32)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:316:27)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:267:3)
      at XMLHttpRequestEventTargetImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:214:9)
      at fireAnEvent (node_modules/jsdom/lib/jsdom/living/helpers/events.js:17:36)
      at requestErrorSteps (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:121:3)
      at Object.dispatchError (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:51:3)
      at EventEmitter.<anonymous> (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
      at Request.<anonymous> (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:357:16)
      at Request.onRequestResponse (node_modules/request/request.js:1059:10)

 FAIL  tests/structure.test.js
  ● Console

    console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Error: Response for preflight has invalid HTTP status code 403
          at Object.dispatchError (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:54:19)
          at EventEmitter.<anonymous> (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
          at EventEmitter.emit (events.js:327:22)
          at Request.<anonymous> (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:357:16)
          at Request.emit (events.js:315:20)
          at Request.onRequestResponse (/Users/johnelbasha/code/02-NodeJS/04-Tray-Challenge/trayio-nodejs-test/node_modules/request/request.js:1059:10)
          at ClientRequest.emit (events.js:315:20)
          at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:596:27)
          at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
          at TLSSocket.socketOnData (_http_client.js:469:22) undefined

  ● The exported function › getMaxTemperature returns a number

    Network Error

      at createError (node_modules/axios/lib/core/createError.js:16:15)
      at XMLHttpRequest.handleError (node_modules/axios/lib/adapters/xhr.js:84:14)
      at XMLHttpRequest.<anonymous> (node_modules/jsdom/lib/jsdom/living/helpers/create-event-accessor.js:33:32)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:316:27)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:267:3)
      at XMLHttpRequestEventTargetImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:214:9)
      at fireAnEvent (node_modules/jsdom/lib/jsdom/living/helpers/events.js:17:36)
      at requestErrorSteps (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:121:3)
      at Object.dispatchError (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:51:3)
      at EventEmitter.<anonymous> (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
      at Request.<anonymous> (node_modules/jsdom/lib/jsdom/living/xhr-utils.js:357:16)
      at Request.onRequestResponse (node_modules/request/request.js:1059:10)

Test Suites: 2 failed, 2 total
Tests:       2 failed, 2 total
Snapshots:   0 total
Time:        1.962s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! weatherclient@1.0.0 test: `jest`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the weatherclient@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/johnelbasha/.npm/_logs/2021-03-05T03_55_24_295Z-debug.log

My Node.Js application is has the following key folders/files layout:

  • src/index.js
  • tests/getMaxTemperature.test.js
  • tests/structure.test.js
  • app.js

app.js [ I am not allowed to change this file ]

const readline = require("readline");
const { 
    getMaxTemperature, 
    getAverageSunHoursForLocation } = require('./src/index')


const printOutWeather = async ({location, year}) => {
    const MaxTemperature = await getMaxTemperature({location: location, year: year})

    console.log(`The max temperature for ${location} in ${year} is: ${MaxTemperature}`)
}

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question("Location?\noxford or heathrow ? ", (location) => {
    rl.question("Year? ", (year) => {
        printOutWeather({location: location, year: year})
        rl.close();
    });
});

src/index.js

const axios = require('axios');

// Get maximum Temperature for a year - Must return a number
exports.getMaxTemperature = async ({location, year}) => {
  const baseUrl = 'https://grudwxjpa2.execute-api.eu-west-2.amazonaws.com/dev/';
  const config = { headers: { 'x-api-key': 'mcDLmlxrtw7ZHC70gD8FL4rtrXSPsUEB4iSp4lg3'} };
  const targetUrl = `${baseUrl}${location}/year/${year}`;
  const res = await axios.get(targetUrl, config)
  const tempArray = res.data.result.map(x => x.temperature_max);
  const maxTemp = Math.max(...tempArray);
  console.log(typeof(maxTemp));
  return maxTemp;
}

tests/structure.test.js [ I am not allowed to change this file ]

const { getMaxTemperature, 
    getMinTemperature, 
    getAverageSunHoursForLocation } = require('../src/index')

const LOCATION = 'oxford';
const YEAR = 2018;

describe('The exported function', ()=> {
    it('getMaxTemperature returns a number', async () => {
        const result = await getMaxTemperature({location: LOCATION, year: YEAR})
        expect(typeof result).toEqual('number')
    })
})

tests/getMaxTemperature.test.js

const {getMaxTemperature} = require('../src/index')

describe('getMaxTemperature', () => {
    it('Successfully gets the max Temperature for oxford 2018', async () =>{
        const location = 'oxford';
        const year = 2018;

        const result = await getMaxTemperature({location:location, year:year});

        expect(result).toEqual(27.4)
    });
})

Aucun commentaire:

Enregistrer un commentaire