【问题标题】:Testing Axios in Jest用 Jest 测试 Axios
【发布时间】:2020-11-24 08:21:35
【问题描述】:

我是测试新手。 我正在尝试测试异步数据获取功能,但我无法弄清楚为什么测试没有通过。 我开玩笑地模拟了 Axios,并为 Axios 的 get 方法提供了一个模拟实现来解决一个承诺。 错误说它无法读取 name 的属性,这意味着我认为数据 obj 未定义。

这里是 Yelp.test.js

import Yelp from './Yelp';
import axios from 'axios';

jest.mock('axios');

describe('searchRestaurantsInfo', () => {
  test('returns object with restaurant infos', async () => {
    const data = {
      name: 'Casa Romana',
      address: '5 Albion Street',
      coordinates: { lat: 52.6322649, lng: -1.1314474 },
      city: 'Leicester LE1 6GD',
      rating: 4.5,
      photos: [
        'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
        'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
        'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
      ],
      phone: '+441162541174',
      price: '£££',
      categories: 'Italian',
      url:
        'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_lookup&utm',
      reviews: [
        {
          id: 'i_Q39aN9hwZzGDUb-IWpYw',
          rating: 5,
          text:
            'Proper Italian restaurant. Not Italian-themed, or serving Italian fusion cuisine, just a place with an Italian owner who makes solid, straightforward...',
          time_created: '2014-10-02 03:49:36',
          url:
            'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&hrid=i_Q39aN9hwZzGDUb-IWpYw&utm_campaign=yelp_api_v3&utm_me',
          user: {
            id: '6tPD46XZSFllvgn2vTh51A',
            image_url:
              'https://s3-media3.fl.yelpcdn.com/photo/A4Ww6Ks2P9WsALqOFy9cOA/o.jpg',
            name: 'Espana S.',
            profile_url:
              'https://www.yelp.com/user_details?userid=6tPD46XZSFllvgn2vTh51A',
          },
        },
      ],
    };

    axios.get.mockImplementationOnce(() => Promise.resolve(data));

    await expect(
      Yelp.searchRestaurantsInfo('q_IoMdeM57U70GwqjXxGJw')
    ).resolves.toEqual(data);
  });
});

还有 Yelp.js

import axios from 'axios';

let YELP_API_KEY = process.env.REACT_APP_YELP_API_KEY;

const Yelp = {
   // Provides infos about a single restaurant
  async searchRestaurantsInfo(id) {
    try {
      let response = await axios.get(
        `https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/${id}`,
        {
          headers: {
            Authorization: `Bearer ${YELP_API_KEY}`,
            'X-Requested-With': 'XMLHttpRequest',
            'Access-Control-Allow-Origin': '*',
          },
        }
      );

      let responseRew = await axios.get(
        `https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/${id}/reviews`,
        {
          headers: {
            Authorization: `Bearer ${YELP_API_KEY}`,
            'X-Requested-With': 'XMLHttpRequest',
            'Access-Control-Allow-Origin': '*',
          },
        }
      );

      const parameters = {
        name: response.data.name,
        address: response.data.location.display_address[0],
        coordinates: {
          lat: response.data.coordinates.latitude,
          lng: response.data.coordinates.longitude,
        },
        city: response.data.location.display_address[1],
        rating: response.data.rating,
        photos: response.data.photos,
        phone: response.data.phone,
        price: response.data.price,
        categories: response.data.categories[0].title,
        url: response.data.url,
        reviews: responseRew.data.reviews,
      };
      console.log({ parameters, id });

      return parameters;
    } catch (e) {
      console.log(e);
      return e;
    }
  }}

我得到的错误是

searchRestaurantsInfo
    × returns array of restaurnats obj (66ms)

  ● searchRestaurantsInfo › returns array of restaurnats obj

    expect(received).resolves.toEqual(expected) // deep equality

    - Expected
    + Received

    - Object // data object. I removed it from this error message because too long
    + [TypeError: Cannot read property 'name' of undefined]

      47 |     await expect(
      48 |       Yelp.searchRestaurantsInfo('q_IoMdeM57U70GwqjXxGJw')
    > 49 |     ).resolves.toEqual(data);
         |                ^
      50 |   });
      51 | });
      52 | 

      at Object.toEqual (node_modules/react-scripts/node_modules/expect/build/index.js:202:20)
      at Object.<anonymous> (src/helpers/Yelp.test.js:49:16)

  console.log src/helpers/Yelp.js:91
    TypeError: Cannot read property 'name' of undefined
        at Object.searchRestaurantsInfo (C:\Users\Turi\Desktop\project\RestaurantsRedux\src\helpers\Yelp.js:72:29)
        at processTicksAndRejections (internal/process/task_queues.js:97:5)
        at Object.<anonymous> (C:\Users\Turi\Desktop\project\RestaurantsRedux\src\helpers\Yelp.test.js:47:5)

提前感谢您的帮助!

【问题讨论】:

  • 我只是在这里猜测,但也许你需要在那些地方传递 { data } 而不是 data
  • @tanmay 不,同样的错误。
  • 应该是axios.get.mockImplementationOnce(() =&gt; Promise.resolve({ data })。有 2 个请求,但只有一个模拟,应该有更多。顺便说一句,捕捉错误并返回它不是常规的。

标签: reactjs unit-testing jestjs axios


【解决方案1】:

您等待结果的方式可能有问题(可能是编译问题),请尝试像这样编写测试。

// note make sure the test() function is async

const result = await Yelp.searchRestaurantsInfo('q_IoMdeM57U70GwqjXxGJw')
      expect(result).toEqual(data);

【讨论】:

    【解决方案2】:

    我已经设法找到了解决方案。

    就像建议的那样,我必须添加另一个模拟,因为在函数中有两个不同的请求。

    除此之外,我意识到我不能同时使用data

    axios.get.mockImplementationOnce(() =&gt; Promise.resolve(data));

          Yelp.searchRestaurantsInfo('q_IoMdeM57U70GwqjXxGJw')
        ).resolves.toEqual(data);```
    

    因为该函数没有返回data,而是一个包含data 中某些部分的对象。 因此我创建了一个新对象params 与函数返回的对象进行比较。

    import Yelp from './Yelp';
    import axios from 'axios';
    
    jest.mock('axios');
    
    describe('searchRestaurantsInfo', () => {
      test('returns object with restaurant infos', async () => {
        const response = {
          data: {
            name: 'Casa Romana',
            location: {
              display_address: [
                "12 Upper Saint Martin's Lane",
                'London WC2H 9FB',
                'United Kingdom',
              ],
            },
            coordinates: { latitude: 52.6322649, longitude: -1.1314474 },
    
            rating: 4.5,
            photos: [
              'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
              'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
              'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
            ],
            phone: '+441162541174',
            price: '£££',
            categories: [{ alias: 'indpak', title: 'Indian' }],
            url:
              'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_lookup&utm',
          },
        };
    
        const responseRev = {
          data: {
            reviews: [
              {
                id: 'i_Q39aN9hwZzGDUb-IWpYw',
                rating: 5,
                text:
                  'Proper Italian restaurant. Not Italian-themed, or serving Italian fusion cuisine, just a place with an Italian owner who makes solid, straightforward...',
                time_created: '2014-10-02 03:49:36',
                url:
                  'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&hrid=i_Q39aN9hwZzGDUb-IWpYw&utm_campaign=yelp_api_v3&utm_me',
                user: {
                  id: '6tPD46XZSFllvgn2vTh51A',
                  image_url:
                    'https://s3-media3.fl.yelpcdn.com/photo/A4Ww6Ks2P9WsALqOFy9cOA/o.jpg',
                  name: 'Espana S.',
                  profile_url:
                    'https://www.yelp.com/user_details?userid=6tPD46XZSFllvgn2vTh51A',
                },
              },
            ],
          },
        };
    
        const params = {
          name: 'Casa Romana',
          address: "12 Upper Saint Martin's Lane",
          coordinates: { lat: 52.6322649, lng: -1.1314474 },
          city: 'London WC2H 9FB',
          rating: 4.5,
          photos: [
            'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
            'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
            'https://s3-media1.fl.yelpcdn.com/bphoto/4VUq4j1FF-n5bgXjtoC0Xw/o.jpg',
          ],
          phone: '+441162541174',
          price: '£££',
          categories: 'Indian',
          url:
            'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_lookup&utm',
          reviews: [
            {
              id: 'i_Q39aN9hwZzGDUb-IWpYw',
              rating: 5,
              text:
                'Proper Italian restaurant. Not Italian-themed, or serving Italian fusion cuisine, just a place with an Italian owner who makes solid, straightforward...',
              time_created: '2014-10-02 03:49:36',
              url:
                'https://www.yelp.com/biz/casa-romana-leicester?adjust_creative=7GHt4FY-2vjNyIPhQV7wcw&hrid=i_Q39aN9hwZzGDUb-IWpYw&utm_campaign=yelp_api_v3&utm_me',
              user: {
                id: '6tPD46XZSFllvgn2vTh51A',
                image_url:
                  'https://s3-media3.fl.yelpcdn.com/photo/A4Ww6Ks2P9WsALqOFy9cOA/o.jpg',
                name: 'Espana S.',
                profile_url:
                  'https://www.yelp.com/user_details?userid=6tPD46XZSFllvgn2vTh51A',
              },
            },
          ],
        };
    
        axios.get.mockImplementationOnce(() => Promise.resolve(response));
        axios.get.mockImplementationOnce(() => Promise.resolve(responseRev));
    
        await expect(
          Yelp.searchRestaurantsInfo('q_IoMdeM57U70GwqjXxGJw')
        ).resolves.toEqual(params);
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2021-06-09
      • 2017-12-14
      • 2021-05-04
      • 2018-08-20
      • 2021-06-04
      • 2020-12-07
      • 1970-01-01
      • 2019-04-28
      • 2019-09-29
      相关资源
      最近更新 更多