【问题标题】:Axios mock is undefined in unit testAxios mock 在单元测试中未定义
【发布时间】:2021-08-04 22:43:05
【问题描述】:

尝试为登录页面模拟我的 axios,并且在此处测试我的提交方法时变得未定义:

submit() {
  var name = this.username.value.replace(/ /g, '%20')
  var url = 'http://localhost:8080/properties'

  console.log('PRINT THIS OUT')
  axios.get(
    url,  
    {      
    auth: 
    {
      username: name, 
      password: this.password.value
      
    }})
    .then((res) =>{
        console.log('inside AXIOS outside IF')
        console.log('this is the username ' + res.data)
      if(res.data.CurMember.name == this.username.value 
      && name !='' && this.password != '')
      {
        console.log('THIS IS INSIDE THE AXIOS IF')
        this.navigateToHome()
      }
      else
      {
        console.log('THIS IS INSIDE THE AXIOS ELSE')
        this.invalidLogin = true;
      }
    })
    .catch((error) =>{
      console.log('THIS IS INSIDE THE ERROR ')
      console.error(error)
    })
  },

navigateToHome() {
  console.log('THIS IS THE NAVIGATE')
  this.$router.push({name: "HomePage"});
},

这里是调用这个方法的测试:

import BasicLogin from '@/views/BasicLogin.vue'
import {shallowMount, mount, flushPromises} from "@vue/test-utils"
import { createRouter, createWebHistory } from 'vue-router'
import axios from 'axios'


jest.mock('axios', () => ({
            get: jest.fn(() => Promise.resolve({mockDataCorrectLogin})),
    })) 


const mockData = 
[{
    'authType': 'string',
    'CurMember': {
        'name': 'bossman',
        'pass': 'bigboss!!',
        'role': 'string'
    },
    'version': "string"
}]


const mockDataCorrectLogin = 
{
    status: 200,
    data: mockData
}

describe('BasicLogin.vue', () => 
{
let wrapper = null

beforeEach(() => {
    wrapper = mount(BasicLogin, 
    {
        propsData:
        {
           //data go here
           usernameValue: '',
           passwordValue: '',
           
        },
    })
}),

it('Login as bossman, validate routing worked', async () => {
    
    //creates a mock router for the navigation to be used
    const mockRoute = {
        params: {
            id: 1
        }
    }
    const mockRouter = {
        push: jest.fn()
    }
    const wrapper = mount(BasicLogin, {
        global: {
            mocks: {
                $route: mockRoute, 
                $router: mockRouter
            }
        }
    })

    const inputFieldUser = wrapper.get('[type="text"]').element
    inputFieldUser.value = 'bossman'
    expect(inputFieldUser.value).toBe('bossman')

    const inputFieldPass = wrapper.get('[type="password"]').element
    inputFieldPass.value = 'bigboss!!'
    expect(inputFieldPass.value).toBe('bigboss!!')

    //await wrapper.get('button').trigger('click')
    await wrapper.vm.submit()
    //expect(axios.get).toHaveBeenCalledTimes(1)

    //expect(mockRouter.push).toHaveBeenCalledTimes(1)
    //expect(mockRouter.push).toHaveBeenCalledWith({"name": "HomePage"})
})
})

从报错信息可以看出,抛出了axios.get错误, 而不是应用程序继续运行和导航路由器。 这是因为 axios 模拟数据是未定义的。 这是错误:

 PASS  tests/unit/BasicLogin.spec.js
 ● Console

console.log src/views/BasicLogin.vue:73
  PRINT THIS OUT
console.log src/views/BasicLogin.vue:90
  inside AXIOS outside IF
console.log src/views/BasicLogin.vue:91
  this is the username undefined
console.log src/views/BasicLogin.vue:105
  THIS IS INSIDE THE ERROR 
console.error src/views/BasicLogin.vue:106
  TypeError: Cannot read property 'CurMember' of undefined
      at /home/bcduff2/jumpgate/web/src/views/BasicLogin.vue:92:23

所以我想知道为什么在提交方法中未定义axios的数据?任何帮助将不胜感激!

【问题讨论】:

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


    【解决方案1】:

    我能够回答我自己的问题,并在这里为可能有同样问题的其他人发帖:

    我不得不把mock数据直接放到这里的axios mock中

    jest.mock('axios', () => ({
        get: jest.fn(() => Promise.resolve({status: 200, data: {authType: 'string',
        CurMember: {
            name: 'bossman',
            pass: 'bigboss!!',
            role: 'string'
        },
        version: "string"}}))
    })) 
    

    【讨论】:

      【解决方案2】:

      错误表明res.data在:

      axios.get(/*...*/)
        .then((res) => {
          if(res.data.CurMember.name == this.username.value
             ^^^^^^^^
      

      ...这表明您的模拟存在问题:

      jest.mock('axios', () => ({
        get: jest.fn(() => Promise.resolve({mockDataCorrectLogin})),
      }))                                  ^^^^^^^^^^^^^^^^^^^^^^
      

      ...其中不包含名为data 的属性,导致您观察到undefined 错误。

      看起来mockDataCorrectLogin 具有您想要返回的模拟响应(包括data 属性),因此解决方案是解决该对象本身:

      jest.mock('axios', () => ({
        get: jest.fn(() => Promise.resolve(mockDataCorrectLogin)),
      })) 
      

      另外,mockData 是一个数组,但您的代码不需要数组。该数据应该只是一个对象:

      /*
      const mockData = 
      [{
          'authType': 'string',
          'CurMember': {
              'name': 'bossman',
              'pass': 'bigboss!!',
              'role': 'string'
          },
          'version': "string"
      }]
      */
      
      const mockData = 
      {
          'authType': 'string',
          'CurMember': {
              'name': 'bossman',
              'pass': 'bigboss!!',
              'role': 'string'
          },
          'version': "string"
      }
      

      【讨论】:

      • 托尼,感谢您的回复。我按照您所说的进行,现在它似乎正在进入数据,但是我看到了错误:TypeError:无法在同一位置读取未定义的属性“名称”。你能说出为什么这也发现它是未定义的吗?
      • 我看到了这个问题。 mockData 是一个数组,但您的代码不需要数组。使mockData 成为一个对象。查看更新的答案。
      猜你喜欢
      • 2021-08-02
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 2018-07-28
      • 2023-04-01
      • 2018-05-28
      • 2016-04-10
      相关资源
      最近更新 更多