开玩笑的测试失败 - 未定义

发布于 2025-02-11 23:10:05 字数 3864 浏览 0 评论 0原文

我确实有两个Jest测试案例,这些案例似乎失败了,但我不知道怎么了。 它是关于邮政功能的,并以某种方式无法识别它并在获取时会出现错误。

任何想法都赞赏。

这是测试结果所说的:


●测试如果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 }
  

I do have two Jest Test Cases which seem to fail but I dont know what is wrong.
It is about Post functions and somehow it doesnt recognize it and gets the error on fetch.

Any ideas appreciated.

This is what the test outcome says:


● Testing if UI updates correctly › Testing 'updateUI' function...

    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)

And these are the functions:

// 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 }

And the second one

// 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}°C, Low: ${data.weather.min_temp}°C</div>
            <div class="precip">With a chance for ${precip}mm of precipitation</div>
        </div>
    `;
    postHolder.appendChild(newDiv);
  }
  
  export { updateUI }
  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不醒的梦 2025-02-18 23:10:05

迟到的答案,但也许可以帮助某人通过这个问题。

默认情况下,Jest在Node环境中运行测试。因此,根据您的软件包和配置,fetch在您的测试中可能没有可用。

因此,解决方案是在测试环境中添加fetch

选项1:模拟获取

在模块中写下模拟功能,例如模拟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-fetch作为DEV依赖关系。
npm i --save-dev cross-fetch
  1. jest.setup.js | ts中导入它。
import 'cross-fetch/polyfill';
  1. 在执行测试之前,配置开玩笑以加载它。例如,在jest.config.js中。
module.exports = {
  testEnvironment: 'jsdom',
  injectGlobals: true,
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  moduleNameMapper: {
    '\\.(css|less|scss)

在这种方法中,您可以使用 msw testing-library

选项3:使用 Axios 为整个应用程序

使用库 axios 在应用程序中而不是 fetch

然后在测试用例中使用开玩笑模拟 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);
});
: 'identity-obj-proxy', '^@/(.*)

在这种方法中,您可以使用 msw testing-library

选项3:使用 Axios 为整个应用程序

使用库 axios 在应用程序中而不是 fetch

然后在测试用例中使用开玩笑模拟 Axios 模块。


: '<rootDir>/src/$1',
  },
};

在这种方法中,您可以使用 msw testing-library

选项3:使用Axios为整个应用程序

使用库 axios 在应用程序中而不是fetch

然后在测试用例中使用开玩笑模拟Axios模块。

Late answer, but perhaps helps someone passing by this question.

By default, jest runs tests in Node environment. Therefore, depending on your packages and configuration, fetch may not be available in your tests.

Therefore, the solution is to add fetch in the test environment.

Option 1: mock fetch

Write a mock function in a module, say mock-fetch.ts, as follows.

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

Then in your test file, you could use it to mock fetch as follows.

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);
});

In this approch, you could mock fetch only where necessary. On the other hand, the mock implementation might grow complex if you want to test scenarios like network error or response not ok.

Option 2: fetch polyfill only in the test environment

Use a library like cross-fetch while running tests.

This approach is as follows:

  1. Install cross-fetch as a dev dependency.
npm i --save-dev cross-fetch
  1. Import it in jest.setup.js|ts.
import 'cross-fetch/polyfill';
  1. Configure Jest to load it before executing the tests. For example, in jest.config.js.
module.exports = {
  testEnvironment: 'jsdom',
  injectGlobals: true,
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  moduleNameMapper: {
    '\\.(css|less|scss)

In this approach, you could use msw to mock API communication as recommended by testing-library.

Option 3: use a library like axios for the entire app

Use axios instead of fetch in the app.

Then mock the axios module using Jest in the test cases.

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);
});
: 'identity-obj-proxy', '^@/(.*)

In this approach, you could use msw to mock API communication as recommended by testing-library.

Option 3: use a library like axios for the entire app

Use axios instead of fetch in the app.

Then mock the axios module using Jest in the test cases.


: '<rootDir>/src/$1',
  },
};

In this approach, you could use msw to mock API communication as recommended by testing-library.

Option 3: use a library like axios for the entire app

Use axios instead of fetch in the app.

Then mock the axios module using Jest in the test cases.

真心难拥有 2025-02-18 23:10:05

@hellowworl101 答案,option>选项1:模拟fetch,保存一天。

就我而言,我需要其他条目(标题和text())进行提取:

export function mockFetch(data: any, headers: any = null) {
    if (!headers) {
        headers = {'Content-Type': 'application/json'};
    }
    return jest.fn().mockImplementation(() =>
      Promise.resolve({
        ok: true,
        json: () => data,
        headers: new Headers(headers),
        text: () => Promise.resolve(JSON.stringify(data)),
      }),
    );
}

测试是这样的:

import React from "react";
import { render } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";

// Fix the "ReferenceError: Response is not defined" message
// $ npm install whatwg-fetch --save-dev
import 'whatwg-fetch';

// To fix "ReferenceError: fetch is not defined"
import { mockFetch } from './test-helpers/mock-fetch'

import { OneExampleComponent } from "./OneExample";

describe("OneExampleComponent", () => {
    const mockFetchResponse = [{}];
    window.fetch = mockFetch(mockFetchResponse);
    test("renders the OneExampleComponent component", () =>
        React.act(() => {
            render(
                <MemoryRouter>
                    <OneExampleComponent
                        parentData={{}}
                    />
                </MemoryRouter>
            );
        })
    )
});

The @hellowworl101 answer, Option 1: mock fetch, saves the day.

In my case I needed additional entries (headers and text()) for the fetch response:

export function mockFetch(data: any, headers: any = null) {
    if (!headers) {
        headers = {'Content-Type': 'application/json'};
    }
    return jest.fn().mockImplementation(() =>
      Promise.resolve({
        ok: true,
        json: () => data,
        headers: new Headers(headers),
        text: () => Promise.resolve(JSON.stringify(data)),
      }),
    );
}

And the test goes like this:

import React from "react";
import { render } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";

// Fix the "ReferenceError: Response is not defined" message
// $ npm install whatwg-fetch --save-dev
import 'whatwg-fetch';

// To fix "ReferenceError: fetch is not defined"
import { mockFetch } from './test-helpers/mock-fetch'

import { OneExampleComponent } from "./OneExample";

describe("OneExampleComponent", () => {
    const mockFetchResponse = [{}];
    window.fetch = mockFetch(mockFetchResponse);
    test("renders the OneExampleComponent component", () =>
        React.act(() => {
            render(
                <MemoryRouter>
                    <OneExampleComponent
                        parentData={{}}
                    />
                </MemoryRouter>
            );
        })
    )
});

耳钉梦 2025-02-18 23:10:05

就我而言,我只是用

In my case, I just replaced fetch with a library like Axios which is a http client library for the browser and node.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文