【问题标题】:response undefined when using jest mock to test axios in vue在 vue 中使用 jest mock 测试 axios 时响应未定义
【发布时间】:2021-08-02 23:05:38
【问题描述】:

我尝试了很多类似问题的答案,但都没有帮助。 (cmets 是我尝试过的。尝试用空行分隔。我在这里停留了将近一个星期,试图通过测试 Axios 请求的 .then 部分来提高覆盖率。真的无法弄清楚哪个部分出了问题.

代码在这里

__ 模拟 __/axios.js:

export default {
    get: jest.fn(() => Promise.resolve({ data: {} })),
    post: jest.fn(() => Promise.resolve())
}

要测试的getInfo方法:

getInfo () {
      axios.get('/')
        .then((response) => {
          this.form.sid = response.data.data.basic_info.username
          this.form.name = response.data.data.basic_info.name
          this.form.tel = response.data.data.basic_info.mobile_number
          this.form.email = response.data.data.basic_info.email
          return response.data
        }).catch(function (error) {
          console.log(error)
        })
    }

测试代码:

import { shallowMount } from '@vue/test-utils'
import InfoForm from '@/components/InfoForm'

//attempt 1
import axios from 'axios';
jest.mock('axios')

//attempt 2
// import axios from './__mocks__/axios'
// jest.mock('axios')

//attempt 3
// import axios from './__mocks__/axios'
// jest.mock("axios", () => ({
//     post: jest.fn((_url, _body) => {
//       url = _url
//       body = _body 
//       return Promise.resolve()
//     }),
//     get: jest.fn(() => {
//         return Promise.resolve()
//       })
//   }))

//attempt 4
// import axios from "axios"

//...
//describe part is skipped here

    it('test method: getInfo', async () => {
        const mockAxiosGet = jest.spyOn(axios, "get")
        mockAxiosGet.mockResolvedValue(() =>
            Promise.resolve({
                data: {
                    basic_info: {
                        username: 'aName',
                        name: 'aNAME',
                        mobile_number: '12222222222',
                        email: 'amail@em.com'
                    }
                }
            })
    )

        const response = await wrapper.vm.getInfo()
        expect(response).toBeDefined() // error(plz see error message below)
    })

错误信息:

Ensure that a variable is not undefined.

InfoForm.vue test > test method: getInfo
-----
Error: expect(received).toBeDefined()

Received: undefined Jest

非常感谢任何帮助!

【问题讨论】:

    标签: javascript vue.js unit-testing axios jestjs


    【解决方案1】:

    getInfo 是 promise 的常见陷阱。 Promise 不应该被封装,并且应该从包含它们的函数中返回,以便稍后将它们链接起来。即使当前不需要它,稍后也可能需要它来组合或测试功能。不这样做的唯一原因是回调可能需要一个不允许返回承诺对象的特定签名。

    应该是:

    getInfo () {
       return axios.get('/')
       ...
    

    【讨论】:

    • 谢谢!遗憾的是仍然未定义 :( 我也尝试将 getInfo 转换为异步函数并使用 try 块来执行 axios,但没有运气工作。
    • 添加expect(axios.get).toBeCalledWith('/') 使其更具体。如果它通过,它未定义的唯一可能性是它输入catch 并且您没有注意到控制台输出。预计会导致错误的是 response.data.data.basic_info,您没有使用嵌套的 data 对象模拟它。
    • expect(mockAxiosGet).toHaveBeenCalledWith('/') 传递时发生了奇怪的事情,但是,当我添加另一个 data: {} 以将当前的 data:{ basic_info:{...}} 包含在 mockAxiosGet.mockResolvedValue 部分中时,它给了我未定义的信息。但是当我删除catch 和console.log(error) 时,它给了我TypeError: Cannot read property 'data' of undefined
    • 我明白了。应该是mockAxiosGet.mockResolvedValue({ data : ...。看来你嘲讽的方式和mockImplementation一样,是误会了。
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2021-07-23
    相关资源
    最近更新 更多