尝试用玩笑制作一个简单的 Axios 模拟

Posted

技术标签:

【中文标题】尝试用玩笑制作一个简单的 Axios 模拟【英文标题】:Trying to make a simple Axios mock with jest 【发布时间】:2021-02-23 11:56:12 【问题描述】:

我正在尝试理解this example,所以我尝试的第一件事是删除他的axiosConfig.js,所以这个例子看起来更像是我想要解决的当前案例。但是我收到此错误

- Expected
+ Received

  Object 
+   "baseURL": "https://jsonplaceholder.typicode.com/albums",
    "method": "get",
    "url": "/3/photos?_limit=3",
  ,

Number of calls: 1

  39 |         const photos = await getPhotosByAlbumID(3);
  40 |         expect(axios.request).toHaveBeenCalled();
> 41 |         expect(axios.request).toHaveBeenCalledWith( method: 'get', url: '/3/photos?_limit=3' )
     |                               ^
  42 |         expect(photos.length).toEqual(3);
  43 |         expect(photos[0].albumId).toEqual(3)
  44 |     );

问题

谁能弄清楚如何修复失败的测试?

如果我从getPhotosByAlbumId() 中删除baseURL: 'https://jsonplaceholder.typicode.com/albums',但没有baseURLaxios.request() 没有意义。

我在https://repl.it/@SandraSchlichti/jest-playground#index.js有它在线

index.js

const axios = require('axios');

const getPhotosByAlbumId = async (id) => 
    const result = await axios.request(
      baseURL: 'https://jsonplaceholder.typicode.com/albums',
      method: 'get',
      url: `/$id/photos?_limit=3`
    );
    const  data  = result;
    return data;
;

module.exports = getPhotosByAlbumId;

index.spec.js

const axios = require('axios');
const getPhotosByAlbumID = require('./index');

jest.mock('axios', () => 
    return 
        baseURL: 'https://jsonplaceholder.typicode.com/albums',
        request: jest.fn().mockResolvedValue(
            data: [
                
                    albumId: 3,
                    id: 101,
                    title: 'incidunt alias vel enim',
                    url: 'https://via.placeholder.com/600/e743b',
                    thumbnailUrl: 'https://via.placeholder.com/150/e743b'
                ,
                
                    albumId: 3,
                    id: 102,
                    title: 'eaque iste corporis tempora vero distinctio consequuntur nisi nesciunt',
                    url: 'https://via.placeholder.com/600/a393af',
                    thumbnailUrl: 'https://via.placeholder.com/150/a393af'
                ,
                
                    albumId: 3,
                    id: 103,
                    title: 'et eius nisi in ut reprehenderit labore eum',
                    url: 'https://via.placeholder.com/600/35cedf',
                    thumbnailUrl: 'https://via.placeholder.com/150/35cedf'
                
            ]
        )
    
)

describe('test getPhotosByAlbumID ', () => 
    afterEach(() => jest.resetAllMocks());

    it('fetches photos by album id', async () => 
        const photos = await getPhotosByAlbumID(3);
        expect(axios.request).toHaveBeenCalled();
        expect(axios.request).toHaveBeenCalledWith( method: 'get', url: '/3/photos?_limit=3' )
        expect(photos.length).toEqual(3);
        expect(photos[0].albumId).toEqual(3)
    );
);

【问题讨论】:

【参考方案1】:

由于在您的实现中您使用具有 baseURL 的对象调用 axios.request,因此它与您的断言不匹配。

因此,您可以断言必须使用具有 baseURL 的对象调用它

expect(axios.request).toHaveBeenCalledWith(
    baseURL: "https://jsonplaceholder.typicode.com/albums",
    method: "get",
    url: "/3/photos?_limit=3",
);

或者调用该方法的对象必须具有这两个属性:

expect(axios.request).toHaveBeenCalledWith(
    expect.objectContaining( method: "get", url: "/3/photos?_limit=3" )
);

working example

【讨论】:

【参考方案2】:

我会推荐你​​使用Asymmetric Matchers

 expect(axios.request).toHaveBeenCalledWith(
  expect.objectContaining(
    method: 'get',
    url: '/3/photos?_limit=3'
  ))

有时你有一个大对象,没有必要精确匹配你可以选择要比较的对象。

另一个例子可能是:

expect(mock).toHaveBeenCalledWith(expect.objectContaining(
  postalCode: expect.any(Number)
));

这里是你的例子https://repl.it/join/ldayfmqz-yoandrycollazo

【讨论】:

以上是关于尝试用玩笑制作一个简单的 Axios 模拟的主要内容,如果未能解决你的问题,请参考以下文章

如何模拟 axios API 调用?开玩笑

在开玩笑的模拟模块工厂中模拟一个承诺

不能用玩笑模拟模块,并测试函数调用

反应开玩笑模拟 useNavigate()

开玩笑:无法窥探该属性,因为它不是函数;给定的未定义

用玩笑模拟material-ui选择组件