Axios 模拟在单元测试中未定义

时间:2021-05-14 19:05:03

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

尝试为登录页面模拟我的 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的数据在submit方法中是undefined?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

错误表明 res.dataundefined in:

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"
}

答案 1 :(得分:0)

我能够回答我自己的问题,并在此处为可能遇到相同问题的其他人发帖:

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

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