CORS error - Error: Cross origin http://localhost forbidden - in ReactJS/Jest test only
Asked Answered
A

6

15

I'm running into a problem where the request I am making to an outside API is working fine in execution, but when runing a Jest/Enzyme test it gives me a CORS error. The function in question is using a JsonRpc implementation from an API, and using fetch from node-fetch. Not sure if there are settings for CORS I can apply somewhere?

I tried many variations of async waits in Jest/Enzyme testing framework but am still running into issues.

test("it should do something", done => {
    const component = shallow(<CustomComponent />)
    component.instance().customAsyncFunction( result => {
      expect(result.length).toEqual(5)
      done()
    })
    // return component.instance().customAsyncFunction().then(data => {
    //   expect(data.length).toEqual(5)
    // })
  })

I tried the above and a few other methods (like setTimeout and awaiting it) and get the CORS error.

The results I'm getting are:

 console.error
 node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
   Error: Cross origin http://localhost forbidden
       at dispatchError (...\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\xhr-utils.js:65:19)
       at Request.client.on.res (...\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\xmlhttprequest.js:679:38)
       at Request.emit (events.js:198:13)
       at Request.onRequestResponse (...\node_modules\request\request.js:1066:10)
       at ClientRequest.emit (events.js:203:15)
       at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:556:21)
       at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
       at TLSSocket.socketOnData (_http_client.js:442:20) undefined

Any ideas?

Acromion answered 10/11, 2019 at 4:1 Comment(1)
do you run tests in browser? 'cause CORS check is typical to browser but I believe for NodeJS it is not expectedSilicious
P
7

Jest allows you to set a setup script file. This file will be required before everything else and gives you a chance to modify the environment in which the tests will run. This way you can unset XMLHttpRequest before axios is loaded and the adapter type evaluated since imports are hoisted. Link:https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string

In package.json

{
  ...,
  "jest": {
    ...,
    "setupTestFrameworkScriptFile": "./__tests__/setup.js",
    ...
  },
  ...
}
__tests__/setup.js

global.XMLHttpRequest = undefined;
Perse answered 18/11, 2019 at 9:44 Comment(3)
I am actually using XMLHttpRequest. What can I do other than that?Dissepiment
I still needed global.XMLHttpRequest to work so I used a drop in npm install xhr2 then global.XMLHttpRequest = require('xhr2');.Pease
@RichardTylerMiles thanks so much, I was able to get rid of CORS error.Circulate
T
6

The error happens because the external API you call during the tests has a CORS restriction different than Jest's default jsdom one has (http://localhost).

To fix this for Jest v24 - v27 you have to set the appropriate testURL (see the docs) in your Jest config (e.g. jest.config.js):

{
    // Other config values here ...
    "testURL": "http://localhost:8080"
}

In testURL you have to put the actual URL allowed by CORS at your remote API side.

Since v28 the option is organized differentlty via testEnvironmentOptions that requires different update in Jest config.

Tensor answered 25/5, 2022 at 9:21 Comment(0)
V
3

Assuming you actually want to call the real API during your tests rather than just mock it, you'll need to make sure the server sends an appropriate "access-control-allow-origin" header (obviously the exact mechanism for doing this depends on your server platform)

Veii answered 26/3, 2020 at 14:37 Comment(0)
C
1

1) what you're probably looking for is to instead mock the promise or whatever function is being ran using jest.mock(), then assert that that mock was called (with the correct params) Jest tests are unit tests that shouldn't really talk to your API

2) most likely something with your env vars while in test mode, process.env.NODE_ENV is set to "test" during jest which might be changing something or maybe one of your own custom config env vars

Crescint answered 10/11, 2019 at 4:26 Comment(0)
R
1

By settting a testURL option which is a valid URL you want in jest config will resovle this problem.

https://jestjs.io/docs/configuration#testurl-string

Refrigeration answered 16/4, 2021 at 3:52 Comment(0)
H
0

I suggest to use supertest library:

yarn add -D supertest / npm install supertest --save-dev

and call request in your test scripts:

import request from "supertest";

try {
    const response = await request('http://...')
        .post('api/v1/...')
        .send(payload);
    return response.body;
}
catch(err) {
    ...
}
Hippocrene answered 19/7, 2023 at 6:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.