1

I have to test this Component but I am confused about how to test it.how to pass parameters when we create instance of it. Can I use axios-mock-adapter here?? I have used this component in my project.I am new to react testing and using axios for first time. can someone please help me???

This is my ApiClient Component:

import axios from 'axios'
class ApiClient {
  constructor() {
    this.axiosConfig = {
      baseURL: this.getURL(),
      timeout: 1000 * 120, // 120seconds/2minutes
      headers: {
        contentType: 'application/json',
        accept: 'application/json',
        Authorization: `Bearer ${this.getAccessToken()}`,
      },
    }

    this.axiosInstance = axios.create(this.axiosConfig)
  }

  generateCancellationToken() {
    const cancelTokenSource = axios.CancelToken.source()
    const cancelToken = cancelTokenSource.token
    return { cancelToken }
  }

  /**
   *
   * @returns string - The accessToken if present
   */
  getAccessToken() {
    return window.localStorage.getItem('otaAccessToken')
  }

  /**
   *
   * @returns string - The URL if present
   */
  getURL() {
    return window.localStorage.getItem('otaAPIURL')
  }

  //saves otaAccessToken & otaAccessToken in local
  setAccessTokenAndBaseURL(baseUrl, Token) {
    window.localStorage.setItem('otaAccessToken', Token)
    window.localStorage.setItem('otaAPIURL', baseUrl)
    this.updateAxios()
  }

  updateAxios() {
    this.axiosConfig = {
      ...this.axiosConfig,
      baseURL: this.getURL(),
      headers: {
        contentType: 'application/json',
        accept: 'application/json',
        Authorization: `Bearer ${this.getAccessToken()}`,
      },
    }

    this.axiosInstance = axios.create(this.axiosConfig)
  }

  cancelToken = this.generateCancellationToken()

  /**
   * @async
   * @returns {Promise<AxiosResponse>}
   * @params {page, pageSize, sortField, sortOrder, searchKey}
   */
  async fetchOTARequests(page, pageSize, sortField, sortOrder, searchKey) {
    return await this.axiosInstance.get(
      '/otaRequests',
      {
        params: {
          page: page,
          pageSize: pageSize,
          sortBy: sortField,
          sortOrder: sortOrder,
          searchValue: searchKey,
        },
      },
      this.cancelToken,
    )
  }

  /**
   * @async
   * @returns {Promise<AxiosResponse>}
   */
  async validateICCID(iccId) {
    return await this.axiosInstance.get('/iccIds/' + iccId, this.cancelToken)
  }

  /**
   * @async
   * @param {payLoad}
   * @returns {Promise<AxiosResponse>}
   */
  async createOTARequest(payLoad) {
    return await this.axiosInstance.post(
      '/otaRequests',
      payLoad,
      this.cancelToken,
    )
  }
}

export default new ApiClient()
Jaimini Chothwani
  • 145
  • 2
  • 2
  • 11

1 Answers1

0

Yes, you can use axios-mock-adapter to mock out axios calls.

It is easy to use if you are using the axios default instance:

var axios = require("axios");
var MockAdapter = require("axios-mock-adapter");

// This sets the mock adapter on the default instance
var mock = new MockAdapter(axios);

Since you create your own axios instance, you could

  • pass it as a dependency when instantiating ApiClient
  • in your tests pass it to the MockAdapter instance
describe('ApiClass', () => {
  const axiosClient = axios.create(yourConfig);
  const axiosMock = new MockAdapter(axiosClient);
  const apiClient = new ApiClient(axiosClient);

  it('fetches this and that', () => {
    // ...
  })

})

I recommend having a look at Mock Service Worker (MSW). It intercepts requests at network level and responds http requests with mock data. It might be a bit more overhead, but it

  • spares you from mocking axios
  • allows switching to another request-issuing library
  • gives you greater confidence that you use your axios client correctly

This article explains it very well.

geoM
  • 447
  • 4
  • 12
  • In axios.create(yourConfig)-yourConfg did you mean parameters like baseurl ,timeout? – Jaimini Chothwani May 27 '21 at 08:05
  • Can you please tell me what all things to be tested??? Like should I test functions like getURL() or not??? – Jaimini Chothwani May 27 '21 at 09:34
  • I am getting error when I wrote the above code. This is error is:TypeError: _.default is not a constructor on line const apiClient = new ApiClient(axiosClient); – Jaimini Chothwani May 27 '21 at 10:55
  • I assume you want to have high test coverage for your client, so you might want to test every code path, but that is up to you. If you want to test `getUrl`, have a look at how to mock localStorage in Jest tests: https://stackoverflow.com/questions/32911630/how-do-i-deal-with-localstorage-in-jest-tests Regarding the error: How did you import `ApiClient` in your test file? Can you provide a CodeSandbox? https://codesandbox.io/examples/package/jest/index.html – geoM May 27 '21 at 11:22
  • this is how I import -import ApiClient from '.' – Jaimini Chothwani May 27 '21 at 11:25
  • https://codesandbox.io/s/cool-cray-0p741?file=/src/index.js – Jaimini Chothwani May 27 '21 at 11:44
  • Thanks for providing the CodeSandbox. I have problems running the tests there (if I go to the "Tests" Tab on the right, I always see "unning Test Suites..." but not test log, no matter what I do. But I already see a couple of related problems: 1. When exporting the `ApiClient` you are already instantiating it (`export default new ApiClient())`. Try only exporting the class, and instantiate it where it is needed (in tests and in app code). – geoM May 27 '21 at 15:25
  • Thank you for answering. I can't change the code will try another way (mocking adios). – Jaimini Chothwani May 27 '21 at 16:09