Judith Gongora
Judith Gongora

Reputation: 41

Error when testing fetch in vanilla JavaScript with jest-fetch-mock

I'm trying to test a fetch from a class. I need to create a class instance to access the fetch method. If I eliminate the class and return directly, the method works.

I tried to do the test this way, but it returns undefined. Any solution?

Thank you very much

//api.test.js
//import the class Request and module jest-fetch-mock
import Request from './index'
global.fetch = require('jest-fetch-mock')

describe('testing api', () => {
  beforeEach(() => {
    fetch.resetMocks()
  })

  it('calls api and returns data to me', async () => {
    const request = new Request('http://localhost:3000/api.json')
    fetch.mockResponseOnce(JSON.stringify({data: '12345'}))

    // assert on the response
    const res = request.getSections()
    expect(res.data).toEqual('12345')


    // assert on the times called and arguments given to fetch
    expect(fetch.mock.calls.length).toEqual(1)
    expect(fetch.mock.calls[0][0]).toEqual('http://localhost:3000/api.json')
  })
})

//api.js
/**
* Request Component
* @class Request
*/
class Request {
/**
* Creates an instance of Request
*
* @param {String}  url - The url of the API
* @throws {Error} - Incorrect type
* @memberof Request
*/
  constructor(url) {
     if (typeof url !== 'string') throw TypeError(`${url} is not a string`)
     this.url = url
  }

  /**
  * Handler get sections from api
  * @memberof Request
  */
  getSections() {
     return fetch(this.url)// eslint-disable-line
       .then(res => res.json())
       .then(result => result.sections)
       .catch(err => console.error(err)) // eslint-disable-line
  }
}

export default Request

I received:

expect(received).toEqual(expected)

Expected value to equal:
  "12345"
Received:
  undefined

Difference:

  Comparing two different types of values. Expected string but received undefined.

  14 |     // assert on the response
  15 |     const res = request.getSections()
> 16 |     expect(res.data).toEqual('12345')
     |                      ^
  17 |
  18 |
  19 |     // assert on the times called and arguments given to fetch

Res is undefined too. I'm doing something wrong, but I don't know what it is.

Upvotes: 4

Views: 4867

Answers (1)

MatthewG
MatthewG

Reputation: 9303

I see two problems that you can fix to get things working.

The first is that because getSections is an asynchronous function (it returns a promise), you need to call it asynchronously from your test. Your test method is already marked as async, so all you need to do is add the await keyword before the call.

const res = await request.getSections()

Secondly, your Request code is expecting a server response that includes a sections property, which your mock does not have. Try changing your mock to include a sections property, such as:

fetch.mockResponseOnce(JSON.stringify({ sections: { data: "12345" }}));

If you make these two changes, your test should pass.

Upvotes: 2

Related Questions