JEST测试失败-未定义获取

o4hqfura  于 2023-04-03  发布在  Jest
关注(0)|答案(1)|浏览(210)

我确实有两个Jest测试用例似乎失败了,但我不知道哪里出了问题。这是关于Post函数的,不知何故,它没有识别它,并在获取时出错。
任何想法都欢迎。

测试结果如下:

●测试UI是否正确更新›测试'updateUI'函数...

TypeError: Cannot read property 'weather' of undefined

      3 |     console.log('all data returned is:')
      4 |     console.log(data)
    > 5 |     const precip = Math.round(data.weather.precip * 10) / 10
        |                                    ^
      6 |     const postHolder = document.getElementById('all-posts')
      7 |     const newDiv = document.createElement('div');
      8 |     newDiv.classList.add('entry-holder');

      at updateUI (src/client/js/updateUI.js:5:36)
      at Object.<anonymous> (__test__/testUpdateUI.test.js:10:12)


 FAIL  __test__/testPostData.test.js
  ● Testing the posting of the data › Test 'postInput' function to make a successful post

    ReferenceError: fetch is not defined

      1 | // POST input data to server
    > 2 | const postInput = async (url = '', data = {}) => {
        |                   ^
      3 |     const response = await fetch(url, {
      4 |       method: 'POST',
      5 |       credentials: 'same-origin',

      at _callee$ (src/client/js/postData.js:2:19)
      at tryCatch (src/client/js/postData.js:10:2404)
      at Generator._invoke (src/client/js/postData.js:10:1964)
      at Generator.next (src/client/js/postData.js:10:3255)
      at asyncGeneratorStep (src/client/js/postData.js:12:103)
      at _next (src/client/js/postData.js:14:194)
      at src/client/js/postData.js:14:364
      at src/client/js/postData.js:14:97
      at postInput (src/client/js/postData.js:2:16)
      at _callee$ (__test__/testPostData.test.js:13:11)
      at tryCatch (__test__/testPostData.test.js:15:2404)
      at Generator._invoke (__test__/testPostData.test.js:15:1964)
      at Generator.next (__test__/testPostData.test.js:15:3255)
      at asyncGeneratorStep (__test__/testPostData.test.js:17:103)
      at _next (__test__/testPostData.test.js:19:194)
      at __test__/testPostData.test.js:19:364
      at Object.<anonymous> (__test__/testPostData.test.js:19:97)

这些是函数:

// POST input data to server
const postInput = async (url = '', data = {}) => {
    const response = await fetch(url, {
      method: 'POST',
      credentials: 'same-origin',
      headers: { 'Content-Type': 'application/json', },
      body: JSON.stringify(data),
    })
    try {
      const newData = await response.json();
      console.log('newData in postInput function is:')
      console.log(newData)
      Client.updateUI(newData)
    } catch (error) {
      console.log('ERROR in POST:', error);
    }
  }
  
  export { postInput }

第二个

// Fetches gathered data from server & updates UI with it
function updateUI(data) {
    console.log('all data returned is:')
    console.log(data)
    const precip = Math.round(data.weather.precip * 10) / 10
    const postHolder = document.getElementById('all-posts')
    const newDiv = document.createElement('div');
    newDiv.classList.add('entry-holder');
    newDiv.innerHTML =`
        <img src="${data.pix.webformatURL}" alt="destination">
        <div class="stat-holder">
            <div class="wait-time"><i>${data.geo.name}, ${Client.checkCountry(data.geo)} is ${Client.dateDiff()} days away.</i></div>
            <h3>Typical weather for then is:</h3>
            <div class="temp">High: ${data.weather.max_temp}&degC, Low: ${data.weather.min_temp}&degC</div>
            <div class="precip">With a chance for ${precip}mm of precipitation</div>
        </div>
    `;
    postHolder.appendChild(newDiv);
  }
  
  export { updateUI }
62lalag4

62lalag41#

答案晚了,但也许可以帮助路过这个问题的人。
默认情况下,jest在Node环境中运行测试。因此,根据您的包和配置,fetch可能在您的测试中不可用。
因此,解决方案是在测试环境中添加fetch

选项1:模拟取球

在一个模块中编写一个mock函数,比如mock-fetch.ts,如下所示。

export function mockFetch(data: any) {
  return jest.fn().mockImplementation(() =>
    Promise.resolve({
      ok: true,
      json: () => data,
    }),
  );
}

然后在您的测试文件中,您可以使用它来模拟fetch,如下所示。

import { mockFetch } from './mock-fetch';

test('postInput()', async () => {
  window.fetch = mockFetch(someJson);

  // ... your postInput or component render here
  const result = await postInput();

  // Assert your expectations
  expect(result).toEqual(someJson);
});

在这种方法中,你可以只在必要的地方模拟获取。另一方面,如果你想测试网络错误或响应不正常等场景,模拟实现可能会变得复杂。

选项2:仅在测试环境中获取polyfill

在运行测试时使用像cross-fetch这样的库。
该方法如下:
1.安装cross-env作为开发依赖项。

npm i --save-dev cross-fetch

1.将其导入jest.setup.js|ts

import 'cross-fetch/polyfill';

1.配置Jest在执行测试之前加载它。例如,在jest.config.js中。

module.exports = {
  testEnvironment: 'jsdom',
  injectGlobals: true,
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  moduleNameMapper: {
    '\\.(css|less|scss)$': 'identity-obj-proxy',
    '^@/(.*)$': '<rootDir>/src/$1',
  },
};

在这种方法中,您可以使用msw来模拟testing-library推荐的API通信。

选项3:为整个应用程序使用axios等库

在应用程序中使用axios而不是fetch
然后在测试用例中使用Jest模拟axios模块。

import axios from 'axios';

jest.mock('axios');

test('postInput()', async () => {
  const resp = {data: someJson};
  axios.get.mockImplementation(() => Promise.resolve(resp));

  // ... your postInput or component render here
  const result = await postInput();

  // Assert your expectations
  expect(result).toEqual(someJson);
});

相关问题