【问题标题】:CORS POST request throws on Authorization headerCORS POST 请求在授权标头上引发
【发布时间】:2016-11-07 21:41:54
【问题描述】:

我正在尝试向我的 API 发送一个 CORS POST 请求,并且每次我使用“授权”标头时都会引发 TypeError。该请求甚至没有被发送,因此不涉及服务器。但这仅发生在我的测试中。当我在 Chrome 中尝试时,它工作得很好。

这是我正在测试的函数:

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: 'test@person.nu',
        address: 'an adress 123'
      }
    };

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

该应用程序是使用 create-react-app 创建的 react/redux 应用程序,因此我使用 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)

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

我觉得我在这里遗漏了一些明显的东西,但我就是看不到。我查看了 fetch 规范和 jsdom 文档,但无济于事。有什么想法吗?

【问题讨论】:

    标签: javascript ajax cors jestjs jsdom


    【解决方案1】:

    通常你不应该在单元测试中提出真正的请求。处理这个问题的最好方法是使用模拟而不是真正的 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: 'test@person.nu',
            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);
          });
      });
    });
    

    【讨论】:

    • 我可能应该提到我正在使用 nock 模拟请求。我只是暂时离开了那部分以隔离问题。由于请求从一开始就没有被发送,所以此时 mocking 没有任何区别。感谢您的回复:)
    • 即使使用 nock,也会发出真正的请求。这不应该发生在单元测试中。否则,您将测试整个堆栈并发生很多事情,这会使您的测试变得缓慢且不稳定。
    • 你说得有道理。但是仍然 - 即使发送实际请求是一个坏主意,这 应该 工作。但我会听取您的建议,然后改为调用模拟。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 2017-08-13
    • 2014-12-16
    • 2019-04-30
    • 2020-11-12
    • 1970-01-01
    • 2015-03-15
    • 2021-03-24
    相关资源
    最近更新 更多