Rui Han
Rui Han

Reputation: 77

How to mock API calls with axios in Jest?

I'm new to testing and I have some questions about mocking API and axios instance with ES6 class.

I have an index.js:

import axios from 'axios';

export default class Pushkin {
  constructor() {
    this.con = undefined;
  }

  connect(quizAPIUrl) {
    this.con = axios.create({
      baseURL: quizAPIUrl,
    });
  }
  
  prepExperimentRun(userID) {
    const postData = {
      user_id: userID,
    };
    return this.con.post('/startExperiment', postData);
  }
  
  // ......
}

I tried several methods to test it:

import axios from 'axios';
import Pushkin from '../src/index';

jest.mock('axios');

const quizURL = './api/quiz';
axios.create.mockImplementation(() => Promise.resolve(quizURL));

const pushkinClient = new Pushkin();

test('connect to quiz api url', () => {
  pushkinClient.connect(quizURL);
  // Pushkin { con: Promise { './api/quiz' } }
  pushkinClient.con.then((data) => expect(data).toEqual(quizURL));
});

test('prepExp', () => {
  const postData = { data: [{ user_id: 123456 }] };
  axios.post.mockImplementation(() => Promise.resolve(postData));
  pushkinClient.prepExperimentRun(123456).then((data) => expect(data).toBe(postData));
});

When I run the second test prepExp, it throws an error TypeError: this.con.post is not a function. And this.con is Promise { './api/quiz' }.

How should I mock the quizAPIurl in connect(quizAPIurl) instead of just hardcoding it? After that, what is the correct way to mock a axios instance and test POST requests? Thank you.

Upvotes: 2

Views: 2053

Answers (1)

Xinan
Xinan

Reputation: 3162

That's because you didn't mock your create() method right

axios.create.mockImplementation(() => Promise.resolve(quizURL));

This will only gives a Promise<string> back which does not contains post() method. So, of course, it will be "not a function".

One solution is that you can mock an object with a post method:

axios.create.mockImplementation(() => { get: () => {...} });

Another way, which could be smarter but I didn't test, simply returns axois itself.

axios.create.mockImplementation(() => axios);

...

axios.post.mockImplementation(() => Promise.resolve(postData));

Upvotes: 1

Related Questions