【问题标题】:_axios.default.post.mockImplementationOnce is not a function VuesJS_axios.default.post.mockImplementationOnce 不是函数 Vue JS
【发布时间】:2021-03-14 14:15:44
【问题描述】:

我尝试测试我的 API 调用。 我正在使用:

  1. VueJS
  2. 开玩笑
  3. Axios

我在运行此测试时收到错误:“_axios.default.post.mockImplementationOnce 不是函数”:

import axios from 'axios'

let url = ''
let body = {}

jest.mock("axios", () => ({
  //__esModule: true,
  post: (_url, _body) => { 
    return new Promise((resolve) => {
      url = _url
      body = _body
      resolve(true)
    })
  }
}))

//axios.mockResolvedValue();

describe('getGameList', () => {
  test('Success: should return the game list of the user and update gameList in the store', async () => {
    
    const response = {
      data: [ 
        { id:1, name:"game_name1" },
        { id:2, name:"game_name2" }
      ]
    };

    //axios.post.mockResolvedValue(response);
    //OR
    axios.post.mockImplementationOnce(() => Promise.resolve(response));

    expect(url).toBe("api/game_list_of_user")
    expect(body).toStrictEqual({"user_id": 1})

  });

});

有什么线索吗?

编辑1:在tmhao2005的帮助下:

jest.mock("axios", () => ({
  post: jest.fn((_url, _body) => { 
      url = _url
      body = _body
      return Promise.resolve();
    }),
  create: jest.fn(function () {
      return this;
  })
}))

describe('getGameList', () => {
  test('Success: should return the game list of the user and update gameList in the store', async () => {
    
    const url = "api/game_list_of_user";
    const body = {
      "user_id": 1
    };   
    const response = {
      data: [ 
        { id:1, name:"game_name1" },
        { id:2, name:"game_name2" }
      ]
    };
    axios.post.mockResolvedValue(response); //OR axios.post.mockImplementationOnce(() => Promise.resolve(response));

    expect(url).toBe("api/game_list_of_user")
    expect(body).toStrictEqual({"user_id": 1})

    expect(axios.post).toHaveBeenCalledTimes(1);

  });

});

但我仍然有这个问题:

看起来我的模拟 axios 没有被调用。 toHaveBeenCalledTimes 方法是正确的调用方法吗?

编辑 2: 我调用了我的操作并尝试模拟我的上下文。

let url = ''
let body = {}

jest.mock("axios", () => ({
  post: jest.fn((_url, _body) => { 
    return new Promise((resolve) => {
      url = _url
      body = _body
      resolve(true)
    })
  })
}))

//https://medium.com/techfides/a-beginner-friendly-guide-to-unit-testing-the-vue-js-application-28fc049d0c78
//https://www.robinwieruch.de/axios-jest
//https://lmiller1990.github.io/vue-testing-handbook/vuex-actions.html#testing-actions
describe('getGameList', () => {
  test('Success: should return the game list of the user and update gameList in the store', async () => {
    //const commit = jest.fn()
    const MockContext = jest.fn(() => {
      let context= {
        state: {
          user: {
            id:1
          }
        }
      }
      return context
    });
    const response = {
      data: [ 
        { id:1, name:"game_name1" },
        { id:2, name:"game_name2" }
      ]
    };

    axios.post.mockResolvedValue(response); //OR axios.post.mockImplementationOnce(() => Promise.resolve(response));

    await actions.getGameList(axios.post, MockContext)
    expect(url).toBe("api/game_list_of_user")
    expect(body).toStrictEqual({"user_id": 1})

    expect(axios.post).toHaveBeenCalledTimes(1)
    //expect(commit).toHaveBeenCalledWith(mutations.UpdateGameList, true)
  });

  test('Error: an error occurred', () => {
    const errorMessage = 'Error';
    axios.post.mockImplementationOnce(() =>
      Promise.reject(new Error(errorMessage))
    );
  });

});

我现在有这个错误:

【问题讨论】:

    标签: vue.js axios jestjs


    【解决方案1】:

    问题是您现在正在使用您自己的函数来模拟 post 函数,该函数不是 jest.Mock 的类型,这就是不存在方法 mockImplementationOnce 的原因。

    要解决此问题,您可以:

    • 改为返回一个模拟函数:
    jest.mock("axios", () => ({
      post: jest.fn((_url, _body) => {
        url = _url;
        body = _body;    
        return Promise.resolve();
      })
    }));
    
    // You looked like to forget call you action
    
    import yourAction from "path/to/yourAction";
    
    test('Success: ...', async () => {
      // ...  
      axios.post.mockImplementationOnce(() => Promise.resolve(response));
    
      // call your action
      await yourAction();
      
      // ...
      expect(axios.post).toHaveBeenCalledTimes(1);
    });
    
    
    • 或者如果您不再关心url/body,您只需简单地模拟axios 而不实现任何东西:
    jest.mock('axios')
    

    【讨论】:

    • 谢谢,它正在工作。但我还是有问题。它看起来像它没有被调用的模拟。我编辑了我的问题。
    • 嗯。诡异的。如果 expect(url).toBe("api/game_list_of_user") 已通过,这意味着您的模拟已被调用。那里有一个可行的例子吗?
    • 我使用该链接来编写我的模拟函数:lmiller1990.github.io/vue-testing-handbook/… 我不明白为什么我的模拟函数没有被调用
    • 事实是你还没有在你的单位调用你的行动。我给你另一个提示,在更新的答案中调用它
    • 好的,谢谢您的帮助。我调用了我的操作并尝试模拟我的上下文错误:“无法读取未定义的属性 context.state.user.id”我是否以错误的方式模拟了我的上下文?我更新了我的帖子
    【解决方案2】:

    我找到了解决办法:

    import actions from '@/store/actions'
    import mutations from '@/store/mutations'
    import state from '@/store/state'
    import store from '@/store'
    import axios from 'axios'
    
    let url = ''
    let body = {}
    
    jest.mock("axios", () => ({
      post: jest.fn((_url, _body) => { 
        return new Promise((resolve) => {
          url = _url
          body = _body
          resolve(true)
        })
      })
    }))
    
    //https://medium.com/techfides/a-beginner-friendly-guide-to-unit-testing-the-vue-js-application-28fc049d0c78
    //https://www.robinwieruch.de/axios-jest
    //https://lmiller1990.github.io/vue-testing-handbook/vuex-actions.html#testing-actions
    describe('getGameList', () => {
      test('Success: should return the game list of the user and update gameList in the store', async () => {
        const context= {
          state: {
            user: {
              id:1
            }
          },
          commit: jest.fn()
        }
        const response = {
          data: [ 
            { id:1, name:"game_name1" },
            { id:2, name:"game_name2" }
          ]
        };
    
        axios.post.mockResolvedValue(response) //OR axios.post.mockImplementationOnce(() => Promise.resolve(response));
        await actions.getGameList(context)
        expect(axios.post).toHaveBeenCalledWith("api/game_list_of_user",{"user_id":1});
        expect(axios.post).toHaveBeenCalledTimes(1)
        expect(context.commit).toHaveBeenCalledWith("UpdateGameList", response.data)
    
      });
    
      test('Error: an error occurred', () => {
        const errorMessage = 'Error';
        axios.post.mockImplementationOnce(() =>
          Promise.reject(new Error(errorMessage))
        );
      });
    
    });
    
    

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      • 2019-04-08
      • 2021-06-10
      • 2019-02-15
      • 2017-08-21
      相关资源
      最近更新 更多