I'm writing unit tests using vitest on a VueJS application.
As part of our application, we have a collection of API wrapper services, e.g. users.js
which wraps our relevant API calls to retrieve user information:
import client from './client'
const getUsers = () => {
return client.get(...)
}
export default {
getUsers
}
Each of these services utilise a common client.js
which in turn uses axios
to do the REST calls & interceptor management.
For our units tests, I want to check that the relevant url
is called, so want to spy on, or mock, client
.
I have followed various examples and posts, but struggling to work out how I mock an import (client
) of an import (users.js
).
The closest I've been able to get (based on these posts - 1, 2) is:
import { expect, vi } from 'vitest'
import * as client from '<path/to/client.js>'
import UsersAPI from '<path/to/users.js>'
describe('Users API', () => {
beforeEach(() => {
const spy = vi.spyOn(client, 'default') // mock a named export
expect(spy).toHaveBeenCalled() // client is called at the top of users.js
})
test('Users API.getUsers', () => {
UsersAPI.getUsers()
expect(spy).toHaveBeenCalled()
})
})
but it's tripping on:
❯ async frontend/src/api/client.js:3:31
2| import store from '@/store'
3|
4| const client = axios.create({
| ^
5| headers: {
6| 'Content-Type': 'application/json'
where it's still trying to load the real client.js
file.
I can't seem to mock client
explicitly because the import
statements run first, and so client
is imported inside users.js
before I can modify/intercept it. My attempt at the mocking was as follows (placed between the imports and the describe
):
vi.mock('client', () => {
return {
default: {
get: vi.fn()
}
}
})