问题描述
我有以下允许用户登录的 vue 应用程序.我正在运行一个应该登录的单元测试,但在触发提交方法时 axios 不会运行.
I have the following vue app that allows a user to login.I am running a unit test that should login but axios won't run when the submit method is triggered.
测试中按钮触发器调用的Submit方法:
The Submit method being called by button trigger in the test:
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 调用在 submit 方法中被完全忽略了呢?这是显示的错误消息,mockRouter 从未被推送,因为从未进行过 axios 调用
So why is the axios call being totally ignored in the submit method?This is the error message displayed mockRouter was never pushed because the axios call was never made
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)
任何帮助将不胜感激.
推荐答案
jest.mock
被提升以影响导入.为了让 jest.mock
影响顶级 import
,它应该位于测试之外的顶级,它不能被提升到高于它使用的范围.
jest.mock
is hoisted in order to affect imports. In order for jest.mock
to affect top-level import
, it should be located at top level outside a test, it cannot be hoisted higher than a scope where it's used.
函数导出需要使用 jest.fn()
模拟,可以使用 spy API 每次测试更改实现:
Functions exports need to be mocked with jest.fn()
, the implementation can be changed per test with spy API:
axios.get.mockResolvedValue(mockDataCorrectLogin)
如果每个测试都需要一个模拟,jest.mock
可以位于测试内部,之后需要重新导入模块.这仅在需要模拟非函数导出或模块产生需要重新应用的副作用时才需要.
If a mock is needed per test, jest.mock
can be located inside a test, a module needs to be be re-imported after it. This is only needed if non-function exports need to be mocked, or a module produces side effects that need to be reapplied.
这篇关于为什么 Axios 方法没有运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!