jefflau / jest-fetch-mock

Jest mock for fetch
MIT License
886 stars 119 forks source link

Add typings. #22

Closed alexeyeryshev closed 6 years ago

alexeyeryshev commented 7 years ago

Little types are never bad.

phra commented 7 years ago

any update on this? @jefflau i can work on a port of this library to typescript if you are interested in!

jefflau commented 6 years ago

I'm just learning some TypeScript now. If anyone wants to port the whole thing to typescript and explain it let me know!

phra commented 6 years ago

@jefflau if i have some free time i can work on it, but i don't guaranteed it.

kresli commented 6 years ago

any update on this?

jefflau commented 6 years ago

I haven't heard of anyone trying to port it yet. I'm open to it though. If you'd like to work on it let me know

alexeyeryshev commented 6 years ago

Couldn't you just merge this PR? It works pretty well. Not a full port but it's enough for a compiler

jefflau commented 6 years ago

@eryshev I'm not that familiar with how typescript works. I thought it had to all be compiled in typescript. How does this help you exactly?

kresli commented 6 years ago

@jefflau typescript compiler looking for .d.ts files in node_modules. The code doesn't need to be written in ts because definitions could be declared inside .d.ts files. If you want to rewrite the module to typescript, this could be done later and its not really relevant to this particular issue.

alexeyeryshev commented 6 years ago

@jefflau I am sorry I wasn't completely clear. It's called a declaration file. You can use it to provide TS compatibility for the libraries written in JS. Talking an OO language it's just an interface without any implementation. You can find out more about npm integration of type definitions on this page.

Have a nice weekend.

jefflau commented 6 years ago

Oh i think i see how it works now. So basically if you want to use jest fetch mock in your typescript project this file basically helps your compiler give you hints when using this library. If that sounds correct then I don't mind merging this

alexeyeryshev commented 6 years ago

Yeah it is that. I use it in my project since I submitted this PR and it works. I think you can merge it if you didn't change significantly your API since :)

jefflau commented 6 years ago

Okay done. I'd appreciate if people with more typescript experience help me to keep this up to date!

spirosikmd commented 6 years ago

Thank you for this package and for adding typings!

I can't get it to work though. How are the types meant to be used? @eryshev can you give an example?

My example is:

{
  "moduleFileExtensions": ["ts", "js"],
  "transform": {
    "\\.ts$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
  },
  "testMatch": ["**/__tests__/**/*-spec.ts"],
  "setupFiles": ["./test/setup.js"]
}
// test/setup.js
const fetch = require('jest-fetch-mock');

jest.setMock('node-fetch', {default: fetch});
// src/HttpService.ts
import fetch from 'node-fetch';

export class HttpService {
  post<T>(url: string, body: {}): Promise<T> {
    return fetch(url, {
      body: JSON.stringify(body),
      method: 'POST',
    }).then(response => response.json<T>());
  }
}
// src/__tests__/HttpService-spec.ts
import fetch from 'node-fetch';
import {HttpService} from '../HttpService';

describe('HttpService', () => {
  let testContext;

  beforeEach(() => {
    testContext = {};
    testContext.httpService = new HttpService();
  });

  describe('#post', () => {
    it('returns json response using fetch', async () => {
      const response = {items: []};
      fetch.mockResponse(JSON.stringify(response)); // <= ERROR: [ts] Property 'mockResponse' does not exist on type '(url: string | Request, init?: RequestInit) => Promise<Response>'.
      const result = await testContext.httpService.post('url', {data: {}});
      expect(fetch).toHaveBeenCalledWith('url', {body: '{"data":{}}', method: 'POST'});
      expect(result).toEqual(response);
    });
  });
});

Any idea what is wrong?

alexeyeryshev commented 6 years ago

Hi @spirosikmd,

just replicated your project on my desktop. Looks like

import fetch from 'node-fetch';

overrides inferred type for fetch in setup.js. So if you remove this line it should compile.

spirosikmd commented 6 years ago

Hi @eryshev! If I remove this line, the project compiles, but the tests are not working anymore. I get this error:

TypeError: fetch.mockResponse is not a function

My initial error can be fixed if I update the example to:

(fetch as any).mockResponse(JSON.stringify(response));

However, using any is not ideal!

alexeyeryshev commented 6 years ago

Yep as any kills all idea of typing :) What are versions of your packages ? Mine are

"devDependencies": {
    "jest": "^22.1.4",
    "jest-fetch-mock": "^1.4.1",
    "node-fetch": "^1.7.3",
    "ts-jest": "^22.0.1",
    "typescript": "^2.6.2"
  }

and node v6.9.1, npm 3.10.8.

You can try to directly import fetch mock in your test it might help

import * as fetch from 'jest-fetch-mock';
spirosikmd commented 6 years ago

The versions I use are:

"devDependencies": {
  "jest": "^22.1.1",
  "jest-fetch-mock": "^1.4.1",
  "node-fetch": "^1.7.3",
  "ts-jest": "^22.0.1",
  "typescript": "^2.6.2"
}

and node v8.9.4, npm 5.6.0. I am using the jest types as well "@types/jest": "^22.0.1". Do you think this might be the problem?

When I import the fetch mock directly I get the following TypeScript error:

File '<a-path-here>/node_modules/jest-fetch-mock/src/index.d.ts' is not a module.
alexeyeryshev commented 6 years ago

Hi again @spirosikmd. I updated my node to your version and got confused :) First of all it worked for me from command line(node_modules/.bin/jest) and didn't work from VSC. Secondly I was amazed by number of settings that are related to types :) So at the end I figured it out by modifying type definitions in this PR https://github.com/jefflau/jest-fetch-mock/pull/46 Now it has the same behavior in VSC and in manual testing. If you want to try it out, you can manually add updated index.d.ts inside of your node_modules/jest-fetch-mock/src. Make sure to have this import in your test, it will override type definition of fetch from official typescript repository.

import * as fetch from 'jest-fetch-mock';

Perhaps you should set "moduleResolution": "node" in your tsconfig.json if it's not done yet. Let me know please if it works for you.

spirosikmd commented 6 years ago

Hi @eryshev! The changes in #46 work for me! I didn't need to set "moduleResolution": "node" in tsconfig.json. Thank you for your help!

sbley commented 6 years ago

Works fine! Has this made it into a release? I can't see any tags in this repo.