CORS POST请求在授权标头上抛出

CORS POST请求在授权标头上抛出

问题描述:

我想向我的API发送一个CORS POST请求,并且每次使用'授权'标头时都会引发TypeError。该请求甚至没有发送,所以服务器不参与。但是这只发生在我的测试中。当我在Chrome中试用它时,它工作得很好。CORS POST请求在授权标头上抛出

这里是函数,我测试:

export const postNewEmployee = formData => { 
    return fetch('http://localhost:3003', { 
          method: 'POST', 
          headers: { 
           'Authorization': 'Bearer test123', 
           'Content-Type': 'application/json' 
          }, 
          body: JSON.stringify(formData) 
          }) 
          .then(response => response) 
          .catch(error => { 
          throw error; 
          }); 
    }; 

及其试验:

import * as API from './api'; 
describe('postNewEmployee',() => { 

    it('posts the form data asynchronously',() => { 

    let formData = { 
     employee: { 
     name: 'Test Person', 
     email: '[email protected]', 
     address: 'an adress 123' 
     } 
    }; 

    return API.postNewEmployee(formData) 
     .then(json => { 
     expect(json.status).toEqual(201); 
     }).catch(error => { 
     console.log(error); 
     }); 
    }); 
}); 

该应用程序是一个反应/ Redux的应用与创造,react-创建应用程序,所以我使用Jest和JSDOM来测试它。问题是,如果我从fetch()调用注释掉Authorization标头,它可以正常工作。但是,如果我添加该标题,我可以得到:

TypeError: Cannot convert undefined or null to object 
    at Object.getRequestHeader (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:20:23) 
    at setDispatchProgressEvents (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:909:38) 
    at XMLHttpRequest.send (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:700:11) 
    at /Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:429:11 
    at Object.<anonymous>.self.fetch (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:373:12) 
    at Object.<anonymous>.exports.postNewEmployee.formData [as postNewEmployee] (/Users/johanh/Kod/react-app/src/api/api.js:20:10) 
    at Object.it (/Users/johanh/Kod/react-app/src/api/api.test.js:75:16) 
    at Object.<anonymous> (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/build/jasmine-async.js:42:32) 
    at attemptAsync (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1919:24) 
    at QueueRunner.run (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1874:9) 

正如我所说的,这只发生在测试中。在浏览器中,它工作正常。

我觉得我在这里错过了一些明显的东西,但我看不到它。我查看了获取规范和jsdom文档,但无济于事。有任何想法吗?

通常情况下,你不应该在单元测试中提出真正的请求。处理这个问题的最好方法是使用模拟而不是真正的fetch实现。

我假设您使用的是fetch的JS实现。所以你可以设置fetch到你想要的测试中。

import * as API from './api'; 
describe('postNewEmployee',() => { 

    it('posts the form data asynchronously',() => { 
    // set fetch to a mock that always returns a solved promise 
    const fetch = jest.fn((url, options) => return Promise.resolve({status: 201})) 
    global.fetch = fetch; 
    let formData = { 
     employee: { 
     name: 'Test Person', 
     email: '[email protected]', 
     address: 'an adress 123' 
     } 
    }; 
    //test that fetch was called with the correct parameters 
    expect(fetch.mock.calls[0][0]).toBe('http://localhost:3003') 
    expect(fetch.mock.calls[0][1]).toEqual(formData) 
    return API.postNewEmployee(formData) 
     .then(json => { 
     expect(json.status).toEqual(201); 
     }).catch(error => { 
     console.log(error); 
     }); 
    }); 
}); 
+0

我应该提到我用nock来嘲笑请求。我只是暂时离开了这部分,以便隔离问题。由于请求从未被发送,因此嘲笑暂时没有任何区别。感谢您的回复:) – Johanh

+0

即使使用nock,也会提出真正的要求。这不应该发生在单元测试中。否则,你会用很多发生的东西来测试整个堆栈,这会让你的测试变得缓慢和不稳定。 –

+0

你有一点。但仍然 - 即使发送实际的请求是一个坏主意,这*应该*工作。但我会接受你的建议,只是调用模拟。谢谢您的帮助! – Johanh