Giter VIP home page Giter VIP logo

mock-xmlhttprequest's Introduction

Build Status

mock-xmlhttprequest

This library is a mock of XMLHttpRequest that provides a simple interface to simulate interactions with XMLHttpRequest. It is a drop-in replacement for XMLHttpRequest for your tests.

This library implements the XMLHttpRequest interface and handles requests and events as specified in the XMLHTTPRequest specification without using real network requests. You can respond to the mock requests in three ways:

You can simulate responses, upload progress, errors, and other interactions with the mock response methods. These automatically handle lower-level processing such as emitting events and changing the readystate property of XMLHttpRequest.

Table of contents

Installation

via npm (node package manager)

$ npm install mock-xmlhttprequest

Quick start

import { newServer } from 'mock-xmlhttprequest';
import { functionToTest } from '../src/SomethingToTest';

// Adapt based on your testing framework. This example uses Mocha and Chai's syntax.

it('should produce a success response', () => {
  const server = newServer({
    get: ['/my/url', {
      // status: 200 is the default
      headers: { 'Content-Type': 'application/json' },
      body: '{ "message": "Success!" }',
    }],
  });

  try {
    // Installs the server's XMLHttpRequest mock in the "global" context.
    // After this, "new XMLHttpRequest()" creates a mock request to which the server replies.
    server.install(/* optional context; defaults to globalThis */);

    // Do something that send()s an XMLHttpRequest to '/my/url' and returns a Promise
    return functionToTest().then((result) => {
      // This assumes the returned Promise resolves to the parsed JSON response
      assert.equal(result.message, 'Success!');
    });
  } finally {
    // Restore the original XMLHttpRequest
    server.remove();
  }
});

Usage

The XMLHttpRequest mock class is MockXhr. It exposes the same interface as XMLHttpRequest and is a drop-in replacement to test code that uses XMLHttpRequest.

There are two options to control the behavior of MockXhr instances:

Using the mock server

The MockXhrServer class implements the mock server. You create a MockXhrServer with newServer. The MockXhrServer automatically responds to MockXhr requests and makes writing tests easy.

The basic structure of tests that use MockXhrServer is:

import { newServer } from 'mock-xmlhttprequest';

const server = newServer( /* routes */ );
try {
  server.install( /* optional context; defaults to globalThis */ );
  // Test your code that creates XMLHttpRequests
} finally {
  // Reverts server.install() at the end of the test.
  // Only do this after the test case has finished creating XMLHttpRequests.
  server.remove();
}

There are two approaches to make your code use the MockXhr class as a replacement for XMLHttpRequest. This allows the MockXhrServer to respond to requests:

  1. Use install() to globally replace the XMLHttpRequest class with the server's MockXhr class. At the end of the test case, call remove() to restore the original state.
  2. If your code allows you to configure how it creates instances of XMLHttpRequest, use the MockXhr class directly with one of the following MockXhrServer properties:
    • xhrFactory is a function that creates a MockXhr instance.
    • MockXhr is the class of the instances created by xhrFactory.

This code demonstrates usage of xhrFactory:

import { newServer } from 'mock-xmlhttprequest';

const server = newServer( /* routes */ );
const savedFactory = MyClass.xhrFactory;
try {
  MyClass.xhrFactory = server.xhrFactory;
  // Test code that creates XMLHttpRequests through MyClass.xhrFactory()
} finally {
  // Only do this after the test case has finished creating XMLHttpRequests.
  MyClass.xhrFactory = savedFactory;
}

Routes define how the MockXhrServer responds to MockXhr requests. These have three parts:

When you send a MockXhr request, the MockXhrServer finds the first route that matches the request's method and URL. It then responds with the route's request handler. You can also set a default request handler. Request handlers are defined either declaratively or programmatically.

By default, if a request's timeout attribute is set to a non-zero value and MockXhrServer doesn't respond to the request, it eventually times out.

There are two ways to add routes to the MockXhrServer:

The MockXhrServer records all MockXhr requests it receives in a request log. Use this to validate the XMLHttpRequest requests that your code sends.

Simulating progress

The MockXhrServer can generate request (upload) and response (download) progress events automatically. This is disabled by default. Use the progressRate field to enable this.

You can also generate progress events if you respond to MockXhr requests programmatically with a request handler of type Function.

Asynchronous responses

Responses to MockXhr requests are asynchronous. This reproduces how a real XMLHttpRequest request works. You therefore most likely need to use your test framework's asynchronous test support. For example, the relevant documentation for the Mocha test framework is here.

The onSend lifecycle hook is necessary to respond to MockXhr requests. The mock server handles this automatically. The other option is to use the MockXhr lifecycle hooks directly. In both cases, the onSend lifecycle hook executes after the execution context that calls XMLHttpRequest.send() is done or cleared. Internally this library uses an immediately resolved Promise to get an empty callstack.

Responding to MockXhr requests programmatically

There are several MockXhr methods and properties to respond to requests. These methods allow the following interactions:

  • Inspect request parameters.
  • Simulate upload and download progress.
  • Provide response headers and body.
  • Simulate a request timeout or error.

See the Mock response methods section for details.

The timeout attribute and request timeouts

By default, if you set the timeout attribute of XMLHttpRequest in your code, MockXhr requests automatically time out after the specified delay. This emits the timeout event and cancels the request as described in the specification.

Relying on the passage of time to test how your code handles timeouts generally makes tests brittle and hard to debug. You can instead trigger timeouts programmatically with setRequestTimeout().

Disable automatic request timeouts with one of these options:

Using the MockXhr lifecycle hooks

This is an alternative usage pattern that does not use the MockXhrServer. You instead use the MockXhr lifecycle hooks directly. This requires more code, but you have more control over MockXhr requests.

Note that you can also use the MockXhr lifecycle hooks together with MockXhrServer if you only need to extend the mock server.

Example:

import { newMockXhr } from 'mock-xmlhttprequest';
import { functionToTest } from '../src/SomethingToTest';

// Adapt based on your testing framework. This example uses Mocha and Chai's syntax.

it('should produce a success response', () => {
  // Get a "local" MockXhr subclass
  const MockXhr = newMockXhr();

  // Mock JSON response
  MockXhr.onSend = (request) => {
    const responseHeaders = { 'Content-Type': 'application/json' };
    const response = '{ "message": "Success!" }';
    request.respond(200, responseHeaders, response);
  };

  try {
    // Install in the global context so "new XMLHttpRequest()" creates MockXhr instances
    global.XMLHttpRequest = MockXhr;

    // Do something that send()s an XMLHttpRequest to '/my/url' and returns a Promise
    return functionToTest().then((result) => {
      // This assumes the returned Promise resolves to the parsed JSON response
      assert.equal(result.message, 'Success!');
    });
  } finally {
    // Restore the original XMLHttpRequest
    delete global.XMLHttpRequest;
  }
});

API reference

MockXhrServer class

This class is a mock server that responds to MockXhr requests based on their URL and method.

MockXhrServer setup

MockXhrServer(routes)

Arguments:

  • routes: Object with the initial set of routes of the server. (optional)

In most cases you should use newServer instead of this constructor directly.

The keys of the routes object are HTTP methods. The values are arrays with two elements: [url_matcher, request_handler].

See also Request URL matcher and Request handler.

Example:

const handlerFn = (request) => { request.respond(); };
newServer({
  get: ['/get', { status: 200 }],
  'my-method': ['/my-method', { status: 201 }],
  post: ['/post', [handlerFn, { status: 404 }]],
});
install(context = globalThis)

Arguments:

  • context: If you provide a value, the install method sets the XMLHttpRequest property in this context instead of the global context. (optional)

Installs the server's MockXhr mock in the global context to replace the XMLHttpRequest class. Revert with remove().

remove()

Reverts the changes made by install(). Call this after your tests.

progressRate

If you set progressRate to a number greater than 0, the server automatically generates request (upload) and response (download) progress events. Each progress event increments by progressRate bytes.

progressRate only applies to request handlers of type object.

disableTimeout() and enableTimeout()

These methods disable or enable the effects of the timeout attribute of MockXhr. See "The timeout attribute and request timeouts".

Routes

Routes configure how the server responds to MockXhr requests. Their three parts are described below.

The route concept is loosely based on the Express framework.

HTTP request method

Any string with a valid HTTP request method is allowed. The valid methods include standard methods such as GET, POST, PUT and DELETE, as well as other method names. The standard method names are case insensitive.

Request URL matcher

The request URL matcher can be one of these types:

  • A string (e.g. '/my-url') to match the request's URL exactly.
  • A RegExp to match the request's URL.
  • A Function that returns true if the request's URL matches. The function receives the URL as an argument.
Request handler

The request handler can be one of these types:

  • An object with the response properties. The default values are:

    { status: 200, headers: {}, body: null, statusText: 'OK' }
    
  • A Function that calls the mock response methods directly. The function receives a MockXhrRequest instance as an argument.

  • A string with the value 'error' or 'timeout'. This triggers either an error or timeout respectively.

  • An array of the other request handler types above. The first request gets the first handler, the second gets the second handler and so on. The last handler is reused when there are no further handlers in the array.

For object request handlers, the server automatically adds the Content-Length response header with the length of the response body.

All these handlers are equivalent:

const handlerObj = {};
const handlerFn = (request) => { request.respond(200, { 'Content-Length': '0' }); };
const handlerArray = [{}];

Adding routes

get(urlMatcher, handler)

Arguments:

Adds a route for the GET HTTP method.

post(urlMatcher, handler)

Arguments:

Adds a route for the POST HTTP method.

put(urlMatcher, handler)

Arguments:

Adds a route for the PUT HTTP method.

delete(urlMatcher, handler)

Arguments:

Adds a route for the DELETE HTTP method.

addHandler(method, urlMatcher, handler)

Arguments:

Adds a route for the method HTTP method.

setDefaultHandler(handler)

Arguments:

Sets a default request handler for requests that don't match any route.

setDefault404()

Sets a default request handler that returns 404 responses.

Utilities

xhrFactory

Function that returns a new MockXhr instance.

MockXhr

The MockXhr class that the server hooks into. xhrFactory creates instances of this class.

getRequestLog()

Returns an array of all requests received by the server so far. Each call returns a new array. Each array element is an object with these properties:

  • method: HTTP method string.
  • url: URL string.
  • body: request body
  • headers: request headers as an object. The header names are in lower-case.

MockXhr class

This class is a mock of XMLHttpRequest. This section documents its methods and properties that are not in the specification.

Mock API

MockXhr.timeoutEnabled

This static boolean property controls automatic timeout of requests from all instances of the class.

timeoutEnabled

This boolean property controls automatic timeout from this MockXhr instance.

getResponseHeadersHash()

Returns all response headers as an object. The header names are in lower-case.

MockXhr lifecycle hooks

You can define callback methods for the MockXhr lifecycle hooks at these locations:

  1. A static property on the MockXhr class. The hook applies to all instances of MockXhr and of its subclasses.
  2. A static property on a MockXhr subclass returned by MockXhrServer.MockXhr or newMockXhr(). The hook applies to all instances of that class.
  3. A property on an instance of MockXhr. The hook applies to that instance only.

If you define multiple hooks for a lifecycle event, they are called in the order above.

You should generally prefer the third option which makes it easier to isolate your test cases.

onCreate

Callback method that receives these arguments:

  • xhr: New MockXhr instance.

Use this lifecycle hook to intercept instances of MockXhr when they are constructed.

Called when an instance of MockXhr is created, at the end of its constructor. This lifecycle hook is therefore only available as a static property.

import { MockXhr, newMockXhr } from 'mock-xmlhttprequest';

// Called for all instances of MockXhr and all its subclasses
MockXhr.onCreate = (xhr) => { /*...*/ };

// Called for all instances of this MockXhr subclass
const MockXhrSubclass = newMockXhr();
MockXhrSubclass.onCreate = (xhr) => { /*...*/ };
onSend

Callback method that receives these arguments:

Use this lifecycle hook to respond to a request with the mock response methods.

Called asynchronously after each call to send(). Each call to send() generates a call to onSend with a separate instance of MockXhrRequest.

import { MockXhr, newMockXhr } from 'mock-xmlhttprequest';

// Called for all instances of MockXhr and all its subclasses
MockXhr.onSend = (request) => { /*...*/ };

// Called for all instances of this MockXhr subclass
const MockXhrSubclass = newMockXhr();
MockXhrSubclass.onSend = (request) => { /*...*/ };

// Called for this instance only
const xhr = new MockXhrSubclass();
xhr.onSend = (request) => { /*...*/ };

MockXhrRequest class

Each call to send() creates a MockXhrRequest that contains information about the XMLHttpRequest and provides methods to respond programmatically.

Request data

requestHeaders

A HeadersContainer that contains a copy of the request's headers.

method

A string with the request's HTTP method.

url

A string with the request's URL.

body

The request's body.

withCredentials

A boolean with the request's withCredentials value.

getRequestBodySize()

number of bytes in the request body.

Note: this isn't completely accurate when the body is a multipart/form-data encoded FormData. Headers, encoding, and other factors that contribute to a non-mocked XMLHttpRequest's true body size are not considered. You can use this method to get a floor value for the request's true body size. This is useful to simulate upload progress events.

Mock response methods

These methods provide a programmatic interface to respond to MockXhr requests.

If a call to a response method is invalid, it throws an Error with a message that contains "Mock usage error detected".

uploadProgress(transmitted)

Arguments:

  • transmitted: number of bytes transmitted.

Fires a request upload progress.

You can only call this when the request's body isn't null and the upload isn't complete.

After you call this method, you can use any other mock response method.

respond(status = 200, headers = {}, body = null, statusText = 'OK')

Arguments:

  • status: Response HTTP status number. (optional)
  • headers: object with the response headers. (optional)
  • body: Response body. (optional)
  • statusText: string response HTTP status text. (optional)

Complete response method that sets both the response headers and body. Changes the request's readyState to DONE.

Fires the appropriate events such as readystatechange, progress, and load.

This is a shorthand for setResponseHeaders() followed by setResponseBody().

After you call this method, you can't use other mock response methods. This restriction is lifted if you call open() again.

setResponseHeaders(status = 200, headers = {}, statusText = 'OK')

Arguments:

  • status: Response HTTP status number. (optional)
  • headers: object with the response headers. (optional)
  • statusText: string response HTTP status text. (optional)

Sets the response headers. Changes the request's readyState to HEADERS_RECEIVED.

Fires the appropriate events such as readystatechange, progress, and load.

After you call this method, you can use the following mock response methods:

downloadProgress(transmitted, length)

Arguments:

  • transmitted: number of bytes transmitted.
  • length: number of bytes in the response.

Fires a response progress event. Changes the request's readyState to LOADING if it is HEADERS_RECEIVED.

You must call setResponseHeaders() before this method.

setResponseBody(body = null)

Arguments:

  • body: Response body. (optional)

Sets the response body. Changes the request's readyState to DONE.

Fires the appropriate events such as readystatechange, progress, and load.

Calls setResponseHeaders() if not already called. The response headers then only contain Content-Length with a value equal to the length of the response body.

After you call this method, you can't use other mock response methods. This restriction is lifted if you call open() again.

setNetworkError()

Simulates a network error. Changes the request's readyState to DONE.

Fires the appropriate events including the error event.

After you call this method, you can't use other mock response methods. This restriction is lifted if you call open() again.

setRequestTimeout()

Simulates a request timeout. Changes the request's readyState to DONE.

Fires the appropriate events including the timeout event.

Throws an error if the request attribute is equal to 0 since timeouts do not occur in that case.

After you call this method, you can't use other mock response methods. This restriction is lifted if you call open() again.

newMockXhr()

Returns a new MockXhr subclass.

If you use a different subclass of MockXhr in each test case, it is easier to ensure they are self-contained. For example, if you set the timeoutEnabled static property on a subclass, it only affects that subclass and not the other subclasses created in other test cases. Since subclasses aren't reused, cleanup code that reverts the changes made to a subclass is not required.

newServer(routes)

Arguments:

  • routes: Object with the initial set of routes of the server. (optional)

Returns a new MockXhrServer with its own unique MockXhr subclass. See newMockXhr().

Add routes to the MockXhrServer with the optional routes argument. See the constructor for details.

XMLHttpRequest features

Based on the XMLHTTPRequest specification version '15 August 2022'.

Supported

Partial support

  • overrideMimeType() throws when required, but has no other effect.
  • responseType: '', 'text' and 'json' are fully supported. The responseType values have no effect on the response body passed to setResponseBody().
  • responseXml: the response body isn't converted to a document response. To get a document response, pass it directly as the response body in setResponseBody().
  • responseUrl: the final request URL after redirects isn't automatically set. This can be emulated in a request handler.

Not supported

  • Synchronous requests (i.e. async set to false in open()).
  • Parsing the request URL in open() and throwing SyntaxError on failure.

Contributing

Contributors are welcome! See this guide for more info.

License

MIT

mock-xmlhttprequest's People

Contributors

bebesparkelsparkel avatar berniegp avatar dkozma avatar susnux avatar tomasz-zablocki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mock-xmlhttprequest's Issues

Add a setTimeout() method

Is this issue a feature request or a bug report?
Feature

What is the current behavior?
There is no shortcut method to simulate a timeout condition on the request

What is the expected behavior?
Add a setTimeout() method

Promise Support

It would be really helpful if promise support were added so I could more simply do the following:

const xhr = await new Promise((resolve, reject) => {
  MockXMLHttpRequest.onSend = resolve
  form.dispatchEvent(new Event('submit'))
  setTimeout(() => reject(new Error('timed out')), 50)
})

Tracking changes to the XMLHttpRequest spec

upload progress event incomplete?

Is this issue a feature request or a bug report?
bug report.

What is the current behavior?
When sending an upload progress event using uploadProgress, the event received looks like this:

progress Event {
type: 'progress',
loaded: 1000,
total: 0,
lengthComputable: false
}
total is always 0 and lengthComputable is also always 0 and there is no way to change that. In my tests I'd need to be able to set lengthComputable to true and total to the upload size.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.
Code being tested:

What is the expected behavior?
total and lengthComputable should be set when sending the progress event.

Environment in which you encounter the issue:
Node.js/jest.

  • mock-xmlhttprequest version:6.1.1
  • Node.js version: 12.18.2
  • OS version: macOS 10.15.6

Did this work in a previous version of mock-xmlhttprequest (which)?
No idea.

Do you intend to provide a pull request to address this issue?

lockfile not committed

Seems like you have not committed the package-lock.json

$ npm install
npm notice created a lockfile as package-lock.json. You should commit this file.
added 164 packages in 7.502s

`MockXhr` and `xhrFactory` not available in the TypeScript definitions

Is this issue a feature request or a bug report?
Bug

What is the current behavior?
MockXhrServer.MockXhr and MockXhrServer.xhrFactory not available in the TypeScript definitions.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

What is the expected behavior?
These are available when interfacing with the library in TypeScript

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 7.0.2
  • Node.js version: 12.19.0
  • OS version: macOS 10.15.7

Did this work in a previous version of mock-xmlhttprequest (which)?
Unsure.

Do you intend to provide a pull request to address this issue?
Yes

superagent

Feature Question

Is there any way to make this play with superagent so that send will actually make a super agent request?

Are there any plans to add typescript support to the repo?

Is this issue a feature request or a bug report?
Feature request

What is the current behavior?
No autocomplete in typescript based projects

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

What is the expected behavior?
Autocomplete and type checking in development

Environment in which you encounter the issue:
Development

  • mock-xmlhttprequest version:
  • Node.js version: any
  • OS version: any

Did this work in a previous version of mock-xmlhttprequest (which)?

Do you intend to provide a pull request to address this issue?

Error thrown on computing string sizes in FormData.

Is this issue a feature request or a bug report?

🐛Bug Report

What is the current behavior?
The script throws exception when sending post request on mock scene.
image

Inspecting stack trace of the error, the util function getStringByteLength in src/Utils.js seems using the native Blob to get the length of a string.

🪧Step to reproduce

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

// inject mock-xmlhttprequest somewhere.
const formData = new FormData();
formData.append('name', 'some string in form');
axios.post('https://google.com/', formData, {}, {});

What is the expected behavior?

Maybe it should not throw the error?
Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 7.0.4
  • Chrome version: Version 103.0.5060.114 (Official Build) (x86_64)
  • OS version: MacOS Big Sur

Did this work in a previous version of mock-xmlhttprequest (which)?
Have no idea about previous version of mock-xmlhttprequest.
Do you intend to provide a pull request to address this issue?

🚧fixing PR

The issue is clear: we should use new Blob([string], {type: 'text/plain'}); to create a Blob according to latest
MDN document, I'm creating an PR for this bugfix.

Individual Instances of MockXMLHttpRequest

Is it possible to create individual instances of the MockXMLHttpRequest object?

If not, it would be helpful since I have written my own cleanup method and I'm not sure if it is covering all the bases.

afterEach(() => {
  MockXMLHttpRequest.onSend = undefined
  MockXMLHttpRequest.onCreate = undefined
})

Having an individual instance would ensure that each test would start with a fresh MockXMLHttpRequest object.

Cannot programmatically abort an xhr

Describe the bug

In version 7.0.4 I was able to programmatically abort a request.

In version 8.1.0 this doesn't seem to work anymore: abort isn't defined anymore in MockXhrRequest.

Is there a way to programmatically abort the request in the new version?

Steps to reproduce the behavior:

      beforeAll(() => {
        const MockXhr = MockXMLHttpRequest.newMockXhr()
        global.XMLHttpRequest = MockXhr
    })

    //...
    it('my test', () => {
      global.XMLHttpRequest as any).onSend = (xhr) => {
          // crashes here in version 8.1.0 because abort method isn't defined anymore
          // works as expected in 7.0.4
          xhr.abort()
     }
     // execute code that creates & sends a new XHR
   })

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 8.1.0
  • Node.js version: 18.14.1
  • OS version: Darwin 21.6.0

Mismatch between source code and published code

Describe the bug

The code I get when installing mock-xmlhttprequest 8.1.0 from NPM doesn't seem to match the v8.1.0 tag of your repository.

Steps to reproduce the behavior:

  1. Check out the v8.1.0 tag of your repository. You'll see the following code in src/MockXhrRequest.ts:
downloadProgress(transmitted: number, length: number) {
  this._responseReceiver.downloadProgress(this._requestData, transmitted, length);
}
  1. Add "mock-xmlhttprequest": "^8.1.0" as a dependency to a local project and install it. Looking at node_modules/mock-xmlhttprequest/package.json, you'll see that version is indeed "8.1.0".

  2. Now open node_modules/mock-xmlhttprequest/dist/types/MockXhrRequest.d.ts. You'll see the following signature:

downloadProgress(transmitted: number): void;

It seems that the length parameter is missing here, as well as in node_modules/mock-xmlhttprequest/dist/cjs/MockXhrRequest.cjs. For some reason, the signatures don't seem to match.

Expected behavior

I'd expect the signatures of the installed package to match those of the corresponding tag in the repo. In particular, I'd like to simulate upload and download progress events with current and total bytes, but the second parameter seems to be missing.

Make all functions on `MockXhrServer` chainable

Is your feature request related to a problem? Please describe.
Some functions like setDefault404 or addHandler are chainable, but other are not, like disableTimeout.
It would be great if they would be consist chainable so that you can initialize the server in one chain.

Describe the solution you'd like
Make all configuration functions chainable

Describe alternatives you've considered
multiple lines like:

server
    /*...*/
    .setDefault404()
server.disableTimeout()
server.install()

Do you intend to provide a fix yourself?
If you agree with this request I could try to submit a patch implementing this

Design

I think that the newServer might have a second option to create routes with a router like the express.

In my case i gonna create that to especify empty routes while i develop my frontend.

(it's optional)

Something like that:

image

Add support for PATCH http method

Is this issue a feature request or a bug report?

Bug & Feature

What is the current behavior?

When XHR request is send with PATCH http method it is not recognized and an error is returned.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

Yes, the official list of HTTP methods contains the PATCH method, see:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods

const server = MockXMLHttpRequest.newServer({
	patch: [
		"/api/v1/test/patch",
		{
			status: 204,
			headers: {},
		}
	]
}).install();

What is the expected behavior?

To properly process PATCH method.

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 4.4.1
  • Node.js version: v8.12.0
  • OS version: OSX 10.14.6

Did this work in a previous version of mock-xmlhttprequest (which)?

Don't know.

Do you intend to provide a pull request to address this issue?

Yes.

Solution:

To add PATCH method to the upperCaseMethods array in Util.js file - see https://github.com/berniegp/mock-xmlhttprequest/blob/master/src/Utils.js#L48

Using ArrayBuffer as body in request handler object gives TypeScript type error

Describe the bug
The body property seems to be typed as string | undefined, which does not allow me to set an ArrayBuffer as a response.

Steps to reproduce the behavior:
This request handler object gives a type error (Type 'ArrayBuffer' is not assignable to type 'string')

newServer({
  get: [
    () => true,
    {
      status: 200,
      body: new ArrayBuffer(1024),
    },
  ],
})

Somewhat related: note that an example in the readme for the default value of that object also gives a type error when using that, since body should be string | undefined.
{ status: 200, headers: {}, body: null, statusText: 'OK' }

Expected behavior
Can get it to work by casting that request handler object as any, but I was expecting ArrayBuffer to be an allowed type.

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 8.0.0
  • Node.js version: 16.14.0
  • OS version: OSX 10.15.7

Additional context

Do you intend to provide a fix yourself?
No

timeout attribute throw Mock usage error detected.

Describe the bug

Steps to reproduce the behavior:

Expected behavior

Environment in which you encounter the issue:

  • mock-xmlhttprequest version:
  • Node.js version:
  • OS version:

Additional context

Do you intend to provide a fix yourself?

setTimeout used internally

Is this issue a feature request or a bug report?
Feature request to prevent bugs? Not sure how you would qualify this

What is the current behavior?
The internals of this package uses setTimeout, maybe to simulate async behavior skipping a tick? It's common to mock out setTimeout such as within jest folks use jest.useFakeTimers(). Doing so makes this library stall when making an XHR request.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

  1. Mock setTimeout to not run until you say so
  2. Run test

What is the expected behavior?
Mocking window globals should not impact test runner

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 7.0.4
  • Node.js version: 14.17.5
  • OS version: Mac

Did this work in a previous version of mock-xmlhttprequest (which)?
Not that I'm aware

Do you intend to provide a pull request to address this issue?
I honestly switched to another mock engine because this was impacting a number of tests after we realized we mistakenly had setTimeout actually running in our suite.

Issue when aborting a transaction in progress

Is this issue a feature request or a bug report?

Bug report

What is the current behavior?

  1. xhr.send gets called
  2. In send, the following happens: setTimeout(() => onSend.call(this, this), 0)
  3. Meanwhile, the code will call xhr.abort()
  4. Now, onSend gets called and by default goes to _handleRequest, which will eventually call request handlers even though the request was already aborted. The request handlers might e.g. check the url, which has been deleted by _terminateRequest.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

What is the expected behavior?

Since the request was already aborted, we shouldn't be hitting the handlers or anything.

Environment in which you encounter the issue:

  • mock-xmlhttprequest version: 7.0.4
  • Node.js version: N/A
  • OS version:

Did this work in a previous version of mock-xmlhttprequest (which)?

Do you intend to provide a pull request to address this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.