Home > other >  Test Jest of a class using API calls with Mocks and axios.create()
Test Jest of a class using API calls with Mocks and axios.create()

Time:10-03

Trying to test a UserModel class that makes requests to an API that I want to mock the return, and getting the error:

TypeError: mockHttp.post.mockResolvedValueOnce is not a function

File with the test:

import { IUserApiClientUrls } from '../../../src/interfaces'
import { UserModel } from '@/models/UserModel'
import httpClient from '@/services/index'
import apiClient from '@/services/server.json'

jest.mock('@/services/index')
const mockHttp = httpClient as jest.Mocked<typeof httpClient>

const createSut = () => {
  const urlUser: IUserApiClientUrls = apiClient.user
  return new UserModel(urlUser)
}

afterEach(() => {
  jest.clearAllMocks()
})

 test.only('Given an email and password When executed user login Then the response must have a tokenGiven an email and password When executed user login Then the response must have a token', async () => {
    const name = 'Jolie'
    const email = '[email protected]'
    const password = '123456'

    const dataToken = {
        data: { token: '123.123.123abcd' },
    }

    const sut = createSut()
    mockHttp.post.mockResolvedValueOnce(dataToken)

    const response = await sut.register(name, email, password)
    expect(mockHttp.post).toHaveBeenCalled()
    expect(response).toHaveProperty('token')
})

Class UserModel:

import { IUser, IUserApiClientUrls, IUserLogged, IUserModelApi, IUserApiRegister } from '@/interfaces'
import httpClient from '@/services/index'

export class UserModel implements IUserModelApi {
    constructor(private readonly url: IUserApiClientUrls) {}

    async register(name: string, email: string, password: string): Promise<IUserApiRegister> {
        const params = {
            url: this.url.register,
            payload: {
                name,
                email,
                password,
            },
        }
        return httpClient
            .post(params.url, params.payload)
            .then((response) => response.data)
            .catch((e) => console.error(e))
    }
}

httpClient with axios.create:

import axios, { AxiosInstance } from 'axios'

const API_ENVS = {
    production: '',
    development: '',
    local: 'http://localhost:3000',
}

const httpClient: AxiosInstance = axios.create({
    baseURL: API_ENVS.local,
})

httpClient.interceptors.response.use(
    (response) => response,
    (error) => {
        return error
    }
)

export default httpClient

the error

I've also tried directly mocking axios but it didn't work. what did I do wrong?

Thanks for the help in advance!

CodePudding user response:

You've mocked httpClient but not its implementation. Try adding a factory function to return a mocked post method.

jest.mock('@/services/index', () => ({
  __esModule: true,
  post: jest.fn(),
}));

See https://jestjs.io/docs/jest-object#jestmockmodulename-factory-options


Alternately, assign a post property to your mock

mockHttp.post = jest.fn().mockResolvedValueOnce(dataToken);
  • Related