jquery-mockjax

2018-06-18 admin

jquery-mockjax是什么

什么是jquery-mockjax,The jQuery Mockjax Plugin provides a simple and extremely flexible interface for mocking or simulating ajax requests and responses.

jquery-mockjax介绍、jquery-mockjax使用

$.mockjax.mockedAjaxCalls()* Returns an array of all mocked ajax calls with each entry being the request settings object as passed into the$.mockjax()function * If$.mockjaxSettings.retainAjaxCalls is set to false, this will always be empty

  • Array<Object> $.mockjax.unfiredHandlers()
    • Returns an array of all mock handler settings that have not been used. In other words, if a handler has been used for a $.ajax() call then it will not appear in this array
  • Array<Object> $.mockjax.unmockedAjaxCalls()
    • Returns an array of all unmocked Ajax calls that were made. The array contains the settings object passed into $.ajax({...})
    • If `$.mockjaxSettings.retainAjaxCalls is set to false, this will always be empty
  • void $.mockjax.clearRetainedAjaxCalls()
    • Empties the arrays returned by $.mockjax.mockedAjaxCalls and $.mockjax.unmockedAjaxCalls

Overview: Your First Mock

Our first example will be for a simple REST service for a fortune app with the REST endpoint being /restful/fortune which returns the following JSON message:

{
    "status": "success",
    "fortune" : "Are you a turtle?"
}

To pull the fortune into our page, we’d use the following HTML and jQuery code:

<!DOCTYPE html>
<html>
  <head>
    <title>Fortune App</title>
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  </head>
<body>
  <div id="fortune"></div>
</body>
</html>
$.getJSON("/restful/fortune", function(response) {
  if ( response.status == "success") {
    $("#fortune").html( "Your fortune is: " + response.fortune );
  } else {
    $("#fortune").html( "Things do not look good, no fortune was told" );
  }
});

At this point if we were to run this code it would fail since the REST service has yet to be implemented. This is where the benefit of the Mockjax plugin starts to pay off. The first step in using Mockjax is to include the plugin by just adding a regular script tag:

<head>
  ...
  <script src="vendor/jquery.mockjax.js"></script>
</head>

Once you have that included, you can start intercepting Ajax requests and mocking the responses. So let’s mock out the service by including the following code:

$.mockjax({
  url: "/restful/fortune",
  responseText: {
    status: "success",
    fortune: "Are you a mock turtle?"
  }
});

Defining a JSON string inline requires a JSON.stringify() method to be available. For some browsers you may need to include json2.js, which is included in the lib folder. However, you could also simply provide an already stringified version of your JSON in the responseText property.

If you plan on mocking xml responses, you may also have to include jquery.xmldom.js, which can also be found in the lib folder.

Mockjax in Depth

What Mockjax does at this point is replace the $.ajax() method with a wrapper that transparently checks the URL being requested. If the URL matches one defined by $.mockjax(), it intercepts the request and sets up a mock XMLHttpRequest object before executing the jQuery.ajax() handler. Otherwise, the request is handed back to the native $.ajax() method for normal execution. One benefit in this implementation detail is that by simulating the XMLHttpRequest object, the plugin continues to make use of jQuery’s native ajax handling, so there are no concerns with implementing a custom Ajax workflow.

As you write code to mock responses, there’s great value in the fact that there are no modifications required to production code. The mocks can be transparently inserted. This provides easy integration into most frameworks by including the plugin and mock definitions through your build framework. It’s also possible to include it at run time by listening for a query string flag and injecting the plugin and definitions.

Now let’s look at the various approaches to defining mocks as offered by the plugin. The sections below feature an extensive overview of the flexibility in Mockjax and creating responses.

Data Types Available for Mocking

jQuery is able to handle and parse Text, HTML, JSON, JSONP, Script and XML data formats and Mockjax is able to mock any of those formats. Two things to note: depending upon how you mock out JSON and JSONP you may need to include json2.js for the JSON.stringify() method (older browsers only, typically). Additionally if you mock XML inline, you’ll need to include the xmlDOM plugin that transforms a string of XML into a DOM object. However, if you use the proxy approach outlined below then there should be no need to include either the JSON or XMLDOM plugins in any case.

Detailed Request and Response Definition

Defining a Request to Match

The first thing you need to do when mocking a request is define the URL end-point to intercept and mock. As with our example above this can be a simple string:

$.mockjax({
  url: "/url/to/rest-service"
});

or contain a * as a wildcard:

$.mockjax({
  // Matches /data/quote, /data/tweet etc.
  url: "/data/*"
});

or a full regular expression:

$.mockjax({
  // Matches /data/quote, /data/tweet but not /data/quotes
  url: /^\/data\/(quote|tweet)$/i
});

You can also match against the data option in addition to url:

$.mockjax({
  url:  "/rest",
  data: { action: "foo" }
});

The data option may be a custom matching function returning true of false whether the data is expected or not:

$.mockjax({
  url: "/rest",
  data: function( data ) {
    return deepEqual( data, expected );
  }
});

The data function is a recommended place for assertions. Return true and let a testing framework of choice do the rest:

$.mockjax({
  url: "/rest",
  data: function ( json ) {
    assert.deepEqual( JSON.parse(json), expected ); // QUnit example.
    return true;
  }
});

To capture URL parameters, use a capturing regular expression for the URL and a urlParams array to indicate, ordinally, the names of the paramters that will be captured:

$.mockjax({
  // matches /author/{any number here}/isbn/{any number with dashes here}
  // for example: "/author/1234/isbn/1234-5678-9012-0"
  url: /^\/author\/([\d]+)\/isbn\/([\d\-]+)$/,
  // names of matching params
  urlParams: ["authorID", "isbnNumber"],
  response: function (settings) {
    var authorID = settings.urlParams.authorID;
    var isbnNumber = settings.urlParams.isbnNumber;
    // etc...
  }
});

Defining Multiple Requests

Since version 2.2 it is allowed to define several requests at once. $.mockjax([...]) returns a array of handlers’ indexes. It is possible to reset handler by index. Read more in Removing Mockjax Handlers.

var handlers = $.mockjax([
  {url: '/rest', responseText: 'one'},
  {url: '/rest', responseText: 'two'}
]);

$.mockjax.clear(handlers[0]);

Defining a Response

The second step is to define the type and content of the response. The two main properties you will be dealing with are either responseText or responseXML. These properties mirror the native XMLHttpRequest object properties that are set during a live response. There are three different patterns for specifying the responses: Inline, Proxy, and Callback.

Inline Responses

A simple text response would be:

$.mockjax({
  url: "/restful/api",
  responseText: "A text response from the server"
});

A simple JSON response would be:

$.mockjax({
  url: "/restful/api",
  // You may need to include the [json2.js](https://raw.github.com/douglascrockford/JSON-js/master/json2.js) library for older browsers
  responseText: { "foo": "bar" }
});

Also note that a JSON response is really just a text response that jQuery will parse as JSON for you (and return a JSON object to the success and complete callbacks).

A simple XML response would be:

$.mockjax({
  url: "/restful/api",
  // Need to include the xmlDOM plugin to have this translated into a DOM object
  responseXML: "<document><quote>Hello world!</quote></document>"
});

As you can see, if you have a significant amount of data being mocked this becomes unwieldy. So that brings us to the next pattern: the proxy.

Proxy

In this example below, the Mockjax plugin will intercept requests for /restful/api and redirect them to /mocks/data.json:

$.mockjax({
  url: "/restful/api",
  proxy: "/mocks/data.json"
});

The /mocks/data.json file can have any valid JSON content you want, and allows you to maintain that mock data in its own file for maintainability.

Note: If you’re testing your code with a poxy, it is best to run an actual web server for the tests. Simply loading test/index.html from the file system may result in the proxy file not being loaded correctly. We recommend using something like the http-server npm module.

Callback

In the final response pattern, we can define a callback function on the response property and have it set responseText or responseXML as needed:

$.mockjax({
  url: "/restful/api",
  response: function(settings) {
    // Investigate the `settings` to determine the response...

    this.responseText = "Hello world!";
  }
});

The default version of this callback is synchronous. If you provide both parameters to the callback function, you can use asynchronous code to set the dynamic response.

$.mockjax({
  url: '/restful/api',
  response: function(settings, done) {
    var self = this;
    someAsyncMethod(function(data){
      self.responseText = data;
      done();
    });
  }
});

Note that the callback is given the settings provided to the $.mockjax({...}) method merged with any Ajax settings defined by jQuery or your application. This allows you to thoroughly investigate the request before setting the response body (or headers).

Advanced Mocking Techniques

At this point we’ve looked at a series of basic mocking techniques with Mockjax and will now unpack some of the additional functionality contained in the plugin.

Simulating Response Time and Latency

Simulating network and server latency for a mock is as simple as adding a responseTime property to your mock definition:

$.mockjax({
  url: "/restful/api",
  // Simulate a network latency of 750ms
  responseTime: 750,
  responseText: "A text response from the server"
});

You can also use an interval for responseTime to randomize latency:

$.mockjax({
  url: "/restful/api",
  // Use a random value between 250ms and 750ms
  responseTime: [250, 750],
  responseText: "A text response from the server"
});

Simulating HTTP Response Statuses

It’s also possible to simulate response statuses other than 200 (default for Mockjax) by simply adding a status property.

$.mockjax({
  url: "/restful/api",
  // Server 500 error occurred
  status: 500,
  responseText: "A text response from the server"
});

These forced error status codes will be handled just as if the server had returned the error: the error callback will get executed with the proper arguments.

Setting the Content-Type

You can set the content type to associate with the mock response, in the example below, we’re setting a JSON content type.

$.mockjax({
  url: "/restful/api",
  contentType: "application/json",
  responseText: {
    hello: "World!"
  }
});

Setting Additional HTTP Response Headers

Additional HTTP Response Headers may be provided by setting a key in the headers object literal:

$.mockjax({
  url: "/restful/api",
  contentType: "application/json",
  responseText: {
    hello: "World!"
  },
  headers: {
    etag: "xyz123"
  }
});

Dynamically Generating Mock Definitions

In some situations, all of your REST calls are based upon a URL schema. Mockjax has the ability for you to specify a callback function that is handed the $.ajax request settings. The callback function may then either return false to allow the request to be handled natively, or return an object literal with relevant Mockjax parameters set. Below is an example that rewrites all Ajax requests to proxy to static mocks:

$.mockjax(function(settings) {

  // settings.url might be: "/restful/<service>" such as "/restful/user"

  var service = settings.url.match(/\/restful\/(.*)$/);
  if ( service ) {
    return {
      proxy: "/mocks/" + service[1] + ".json"
    };
  }
  // If you get here, there was no url match
  return;
});

Accessing Request Headers

In some situations, you may need access to the request headers to determine matching or response bodies. To do this, you will need to specify a callback function that is handed the $.ajax request settings:

$.mockjax(function( requestSettings ) {
  // Here is our manual URL matching...
  if ( requestSettings.url === "/restful/user" ) {
    // We have a match, so we return a response callback...
    return {
      response: function( origSettings ) {

      	// now we check the request headers, which may be set directly
      	// on the xhr object through an ajaxSetup() call or otherwise:

      	if ( requestSettings.headers["Authentication"] === "some-token" ) {
      	  this.responseText = { user: { id: 13 } };
      	} else {
  		  this.status = 403;
  		  this.responseText = "You are not authorized";
        }
      }
    };
  }
  // If you get here, there was no url match
  return;
});

Forced Simulation of Server Timeouts

Because of the way Mockjax was implemented, it takes advantage of jQuery’s internal timeout handling for requests. But if you’d like to force a timeout for a request you can do so by setting the isTimeout property to true:

$.mockjax({
  url: '/restful/api',
  responseTime: 1000,
  isTimeout: true
});

Dynamically Generating Mock Responses

It’s also possible to dynamically generate the response text upon each request by implementing a callback function on the response parameter:

$.mockjax({
  url: "/restful/webservice",
  dataType: "json",
  response: function(settings) {
    this.responseText = {
      randomText: "random " + Math.random()
    };
  }
});

Data Types

Many of the examples above mock a json response. You can also mock xml:

$.mockjax({
  url: "/some/xml",
  dataType: "xml",
  responseXML: "<document><say>Hello world XML</say></document>"
});

(Don’t forget that it’s likely you’ll need the xmlDOM library as well!)

And html:

$.mockjax({
  url: "/some/webservice",
  dataType: "html",
  responseText: "<div>Hello there

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-34286.html

文章标题:jquery-mockjax

回到顶部