Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supports running mocks in Node #146

Merged
merged 23 commits into from May 16, 2020
Merged

Supports running mocks in Node #146

merged 23 commits into from May 16, 2020

Conversation

kettanaito
Copy link
Member

@kettanaito kettanaito commented May 8, 2020

Changes

  • Adds support for running the same mock definition in Node environment.
  • Breaking: req.url is now an instance of URL, not a string.
  • Breaking: req.query is removed in favor of req.url.searchParams.

GitHub

Roadmap

  • Configure build to produce node-oriented module with setupServer
  • Ensure the node-oriented part is TypeScript-ready
  • Convert intercepted request to mocked request (headers, params, query, etc.)
  • Deal with res() function, that uses new Headers() instance, which does not exist in Node (also affecting ctx.fetch(): ctx.fetch() not keeping original headers #145, Issue #145 ctx.fetch() not keeping original headers #149)
  • Provide a basic set of integration tests (fetch/http/https/xhr)
  • Configure node bundle to properly rely on system modules (https, tty, etc.).
  • Resolve the circular EventEmitter dependency issue:
(!) Circular dependencies
node_modules/util/util.js -> node_modules/util/node_modules/inherits/inherits.js -> node_modules/util/util.js
node_modules/util/util.js -> node_modules/util/node_modules/inherits/inherits.js -> /Users/kettanaito/Projects/mswjs/msw/node_modules/util/util.js?commonjs-proxy -> node_modules/util/util.js
[!] Error: 'EventEmitter' is not exported by node_modules/events/events.js, imported by node_modules/node-request-interceptor/lib/http/ClientRequest/Socket.js
https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
node_modules/node-request-interceptor/lib/http/ClientRequest/Socket.js (1:9)
1: import { EventEmitter } from 'events';
            ^
2: export class Socket extends EventEmitter {
3:     constructor(options, socketOptions) {
Error: 'EventEmitter' is not exported by node_modules/events/events.js, imported by node_modules/node-request-interceptor/lib/http/ClientRequest/Socket.js
  • Remove Node-related modules from rest-deps.js chunk.

Testing scenarios

CRA + @testing-library/react

    TypeError: Invalid URL: /login

      2152 |             this.readyState = this.LOADING;
      2153 |             this.data = data || '';
    > 2154 |             const url = new URL(this.url);
           |                         ^
      2155 |             const req = {
      2156 |                 url: cleanUrl(url),
      2157 |                 method: this.method,

@kettanaito kettanaito changed the title 104 node support Supports running mocks in Node May 8, 2020
@kettanaito kettanaito force-pushed the 104-node-support branch 2 times, most recently from ae59b69 to 8013222 Compare May 11, 2020 17:13
@kettanaito
Copy link
Member Author

After adopting the headers-utils library the headers of the mocked response are joined with a ",", not ", " (missing space). That is a minor difference, and shouldn't affect anything, but I'd like to debug why exactly that happened.

@kettanaito kettanaito marked this pull request as ready for review May 14, 2020 08:16
src/context/body.test.ts Outdated Show resolved Hide resolved
src/mockServiceWorker.js Show resolved Hide resolved
src/node/setupServer.ts Show resolved Hide resolved
src/setupWorker/glossary.ts Outdated Show resolved Hide resolved
src/utils/getResponse.ts Outdated Show resolved Hide resolved
src/utils/handleRequestWith.ts Show resolved Hide resolved
@kettanaito kettanaito marked this pull request as draft May 14, 2020 08:28
@kettanaito kettanaito marked this pull request as ready for review May 14, 2020 08:48
@kettanaito
Copy link
Member Author

kettanaito commented May 15, 2020

Need to make sure this is the expected behavior from Rollup:

(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
http (imported by node_modules/node-request-interceptor/lib/http/override.js, http?commonjs-external, node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js)
https (imported by node_modules/node-request-interceptor/lib/http/override.js, https?commonjs-external)
util (imported by node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js, node_modules/debug/src/node.js, util?commonjs-external)
tty (imported by node_modules/debug/src/node.js, tty?commonjs-external, node_modules/supports-color/index.js)
events (imported by node_modules/node-request-interceptor/lib/http/ClientRequest/Socket.js)
os (imported by node_modules/supports-color/index.js, os?commonjs-external)
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/node-request-interceptor/lib/index.js
3: import require$$0 from 'debug?commonjs-proxy';
4:
5: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
6:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js
3: import require$$0 from 'debug?commonjs-proxy';
4:
5: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
6:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/node-request-interceptor/lib/XMLHttpRequest/XMLHttpRequest/XMLHttpRequestOverride.js
3: import require$$0 from 'debug?commonjs-proxy';
4:
5: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
6:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence

Edit: This error doesn't occur anymore after node-requrest-interceptor is bundled to ES5 format (mswjs/interceptors#11).

@kettanaito
Copy link
Member Author

I've tried to create a unit test example that asserts a component's behavior that uses axios, but it turns out axios cannot run in Node. Examples I find suggest to use an adapter, or to mock the axios' implementation. Either of those look greatly unreliable to me.

@kettanaito kettanaito merged commit 15a7368 into master May 16, 2020
@kettanaito kettanaito deleted the 104-node-support branch May 16, 2020 10:16
@kettanaito kettanaito added the scope:node Related to MSW running in Node label May 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope:node Related to MSW running in Node
Projects
None yet
1 participant