0

我有以下允许用户登录的 vue 应用程序。我正在运行一个应该登录的单元测试,但在触发提交方法时 axios 不会运行。

测试中按钮触发器调用的 Submit 方法:

methods: {
submit() {

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

  axios.get(
    url,  
    {      
    auth: 
    {
      username: name, 
      password: this.password.value
      
    }})
    .then((res) =>{
      if(res.data.CurMember.name == this.username.value 
      && name !='' && this.password != '')
      {
        this.navigateToHome()
      }
      else
      {
        this.invalidLogin = true;
      }
    })
    .catch((error) =>{
      console.error(error)
    })
  },

navigateToHome() {
  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'

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

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

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

it('Login as bossman, validate routing worked', async () => {
    
    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!!')

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

    //This is where the submit is being called
    await wrapper.vm.submit();

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

那么为什么在提交方法中完全忽略了 axios 调用呢?这是显示的错误消息 mockRouter was never push 因为从未进行过 axios 调用

 FAIL tests/unit/BasicLogin.spec.js
 ● BasicLogin.vue › Login as bossman, validate routing worked

expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 1
Received number of calls: 0

88 |
89 |         await flushPromises()
> 90 |         expect(mockRouter.push).toHaveBeenCalledTimes(1)
 |                                 ^
91 |         expect(mockRouter.push).toHaveBeenCalledWith({"name": "HomePage"})
92 |         
93 |     })

at Object.<anonymous> (tests/unit/BasicLogin.spec.js:90:33)

任何帮助将非常感激。

4

1 回答 1

0

jest.mock为影响进口而吊装。为了jest.mock影响顶层import,它应该位于测试之外的顶层,它不能被提升到高于它使用的范围。

函数导出需要用 模拟jest.fn(),可以使用 spy API 每次测试更改实现:

axios.get.mockResolvedValue(mockDataCorrectLogin)

如果每个测试都需要一个模拟,jest.mock可以位于测试内部,则需要在它之后重新导入一个模块。仅当需要模拟非函数导出或模块产生需要重新应用的副作用时才需要这样做。

于 2021-05-14T14:30:35.557 回答