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.
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"});
},
The test:
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"})
})
})
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)
Any help would be much appreciated.
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.
Functions exports need to be mocked with jest.fn()
, the implementation can be changed per test with spy API:
axios.get.mockResolvedValue(mockDataCorrectLogin)
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.