Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing: mocking node-fetch dependency that it is used in a class method

I have the following situation:

A.js

import fetch from 'node-fetch'
import httpClient from './myClient/httpClient'

 export default class{
    async init(){
       const response = await fetch('some_url')
       return httpClient.init(response.payload)
    }
}

A_spec.js

import test from 'ava'
import sinon from 'sinon'
import fetch from 'node-fetch'
import httpClient from './myClient/httpClient'
import A from './src/A'

test('a async test', async (t) => {
    const instance = new A()
    const stubbedHttpInit = sinon.stub(httpClient, 'init')
    sinon.stub(fetch).returns(Promise.resolve({payload: 'data'})) //this doesn't work

    await instance.init()
    t.true(stubbedHttpInit.init.calledWith('data'))
})

My idea it's check if the httpClient's init method has been called using the payload obtained in a fetch request.

My question is: How I can mock the fetch dependency for stub the returned value when i test the A's init method?

like image 722
Gonzalo Pincheira Arancibia Avatar asked May 14 '17 05:05

Gonzalo Pincheira Arancibia


People also ask

What does fetch mock do?

fetch-mock allows mocking http requests made using fetch or a library imitating its api, such as node-fetch or fetch-ponyfill. It supports most JavaScript environments, including Node. js, web workers, service workers, and any browser that either supports fetch natively or that can have a fetch polyfill installed.

How do you mock in node JS?

In Jest, Node. js modules are automatically mocked in your tests when you place the mock files in a __mocks__ folder that's next to the node_modules folder. For example, if you a file called __mock__/fs. js , then every time the fs module is called in your test, Jest will automatically use the mocks.


2 Answers

Finally I resolved this problem stubbing the fetch.Promise reference like this:

sinon.stub(fetch, 'Promise').returns(Promise.resolve(responseObject))

the explanation for this it's that node-fetch have a reference to the native Promise and when you call fetch(), this method returns a fetch.Promise. Check this out

like image 192
Gonzalo Pincheira Arancibia Avatar answered Sep 28 '22 09:09

Gonzalo Pincheira Arancibia


sinon.stub(fetch) can't stub a function itself. Instead you need to stub the node-fetch dependency from inside ./src/A, perhaps using something like proxyquire:

import proxyquire from 'proxyquire`
const A = proxyquire('./src/A', {
  'node-fetch': sinon.stub().returns(Promise.resolve({payload: 'data'}))
})
like image 26
Mark Wubben Avatar answered Sep 28 '22 07:09

Mark Wubben