Node.JS environments don’t have fetch. Ok, so what, I’ll just use node-fetch, right? Yes, but when I was unit testing a VueJS app, this didn’t work. I think it was because of an incompatibility with jsdom. My colleagues and I were getting this error:
TypeError: Cannot set property 'Headers' of undefined at Object../node_modules/node-fetch/browser.js (/app/public/v2/js/webpack:/node_modules/node-fetch/browser.js:23:1)
We bailed on using node-fetch and opted to just mock the fetch instead.
- This example uses Sinon.JS.
fetch
didn’t exist onglobal
which typescript was complaining about. Using anany
type assertion got around this.- The
json
property on a fetch response is actually a function that returns a ~~Promise~.
interface FakeResponse {
readonly ok: boolean;
readonly status: number;
json(): Promise<any>;
}
describe('something', () => {
const data = { foo: 'bar' }
const fakeJson = sinon.fake.resolves(data);
const fakeResponse: FakeResponse = { ok: true, status: 200, json: fakeJson };
const fetchStub = sinon.stub();
fetchStub.withArgs('https://example.com/posts.json').resolves(fakeResponse);
beforeEach(() =>{
(<any>global).fetch = fakeFetch;
})
afterEach(() => {
delete (<any>global).fetch;
})
it('gets the data', (done) => {
const someApi = new SomeApi();
expect(someApi.someMethodThatUsesFetch())
.to.eventually.deep.equal(data)
.notify(done);
})
})