Using Sinonjs fakeserver to handle numerous ajax requests

I utilize QUnit in combination with sinon. Is there a way to make sinon's fakeserver respond to multiple chained ajax calls triggered from the same method?

module('demo', {
    beforeEach: function(){
        this.server = sinon.fakeServer.create();
    },
    afterEach: function(){
        this.server.restore();
    }
});

test('chained ajax calls', function(assert){

    this.server.respondWith('GET', '/foo', [200, 
    { 'Content-Type': 'application/json' }, '{ "foo": 1 }' ]);

    this.server.respondWith('GET', '/bar', [200, 
    { 'Content-Type': 'application/json' }, '{ "bar": 1 }' ]);

    var successCount = 0;

    $.get('/foo', function(data){
        successCount++;
        $.get('/bar', function(){
            console.log('bar success');
            successCount++;
        });
    });

    this.server.respond();
    assert.strictEqual(successCount, 2);
});

The issue I am facing is that only one of the methods returns a response. Can the fakeserver handle this situation effectively?

Update: It appears that adding another server.respond() resolves the problem. However, is there a more efficient approach available?

Based on the documentation, it suggests that one call should suffice, regardless of the number of ajax calls:

server.respond(); Triggers responses for all pending asynchronous requests.

Check out the Fiddle here: http://jsfiddle.net/3qj20r5m/1/

Answer №1

It seems that server.repond() was expected to handle the task, however, I find it easier to set up my fake server(s) to automatically respond instead. This is especially useful when there is no need to inspect requests before responding:

var server;
QUnit.module('fake server tests', {
    beforeEach: function() {
        server = sinon.fakeServer.create();

        // *** it's this option I'm referring to...
        server.autoRespond = true;

        server.respondWith('GET', '/foo', [200, { 
            'Content-Type': 'application/json',
            '{ "foo": 1 }'  
        }]);

        server.respondWith('GET', '/bar', [200, { 
            'Content-Type': 'application/json',
            '{ "bar": 1 }'  
        }]);
    },
    afterEach: function() {
        server.restore();
    }
});

QUnit.test('perform ajax calls', function(assert) {
    var done = assert.async();

    doTwoAjaxCalls(function () {

        // any necessary assertions...
        // (ensure your method includes the callback...)

        done();
    });
});

UPDATE

After reviewing your updated code, it appears clear why calling respond() twice is required: the first call releases the initial ajax request to

/foo</code), triggering the first success callback. Within this callback, the second ajax call is initiated and Sinon holds it until another call to <code>respond()
.

In summary, using autoRespond eliminates the need for multiple respond() calls, as Sinon responds immediately. However, ensuring the test is asynchronous in this scenario is recommended.

Best of luck!

Answer №2

The documentation for Sinon explains that using the autoRespond feature in tests may lead to asynchronous execution, causing potential race conditions due to a slight delay of 10ms before responding. I encountered this issue while testing nested AJAX calls.

To address this, I introduced a new property called respondImmediately to the fakeServer, allowing synchronous responses to requests. This enhancement was recently added in version 1.14.0 of the project. Make sure to update to the latest version to access this feature. You can find more information in the documentation here.

To apply this change in your tests, instead of enabling the autoRespond property in the beforeEach block, enable the respondImmediately property. Remove all instances of server.respond() calls and you should be good to go!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Crafting an integrated REST API model with interconnected data

This question revolves around the implementation of a specific scenario rather than a problem I am facing. Let's say we have a User and a Resource, where a User can have multiple Resource but a Resource can have only 1 User. How should API endpoints b ...

Tips for utilizing JSON and ajax smoothly without encountering any errors

I am attempting to retrieve JSON data from an external PHP file using AJAX and populate it into a dropdown list. After successfully setting up XAMPP with Apache and Mysql, I managed to make everything work for one JSON object. However, when I tried adding ...

Mapping various sets of latitudes and longitudes on Google Maps

I am working with multiple latitude and longitude coordinates. var latlngs = [ {lat:25.774252,lng:-80.190262}, {lat:18.466465,lng:-66.118292}, {lat:32.321384,lng:-64.757370}, {lat:25.774252,lng:-80.190262}, ]; The coordinates were ret ...

Creating multiple child processes simultaneously can be achieved by spawning five child processes in parallel

My goal is to simultaneously run five spawn commands. I am passing five hls stream urls to the loop, and these streamlink commands are meant to record the video for 5 seconds before terminating those processes. I have attempted various async methods but a ...

When running an AJAX script, Datatables Buttons may not be displayed

Below are two blocks of code that I am working with: <script> $(function () { $("#example1").DataTable({ "responsive": true, "lengthChange": false, "autoWidth": false, "buttons": [&qu ...

Encountered a runtime error while trying to insert a list item <li> into a paragraph <p> element

Take a look at this code snippet: <%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication18._Default" %> <!DOCTYPE html> <html> <body> <p id="someId"></p& ...

Fluid sifting and interactive webpage

I'm almost done with my website, but I'm facing a problem. There are 3 blocks of text on my page - 2 static and 1 dynamic. When I click a button, the page should change, which is working fine. However, when I added smooth scroll to the website, ...

Creating SVG paths using coordinates for THREE.js

I copied the exact code from this ThreeJs Example designed for generating a three-dimensional City Model. I've created an SVG path outlining city boundaries using Google Maps and now I'm trying to use the above code to create a similar 3D object ...

Google Extension PHP Plugin

Is it feasible to integrate a PHP file into a Google Extension for Chrome? I've been exploring the idea of creating an extension and most resources only mention HTML, CSS, and JavaScript. Any guidance on using PHP in the extension would be highly valu ...

Activate text-entry fields after a button has been pressed on polymer 1.0

I am currently developing a project focused on creating a list of doctors using the Polymer 1.0 framework. Within the doctor-list, I have integrated a Vaadin grid called doctors-grid.html to display data sourced from a JSON file. Upon double-clicking on a ...

Tips for incorporating MIDI player for notes sequence using MIDI.js

Incorporating MIDI.js into my current project to play a sequence of MIDI notes. See below for the code snippet: for (var repeat = 0; repeat < melodyrepititions; repeat++) { for (var i = 0; i < composition.length; i++) ...

Display data from a PHP array in a JavaScript alert box

Within my Wordpress registration form, I am attempting to display the $error array in an alert message. I have experimented with using console.log(), but it does not show any output. Even when using JSON.stringify(), the alert only displays the word: true ...

The presence of asynchronous JavaScript can lead to errors due to missing functions in JavaScript

I've encountered an issue with a jQuery script that I modified by adding an ASYNC attribute. Surprisingly, it functions correctly in Firefox but encounters intermittent failures in both Chrome and IE browsers. Here's the PHP code snippet respons ...

What is the purpose of the `Bitwise operator |` in the `d3.shuffle` source code and how can it be understood

Learning about the Bitwise operator | can be found in the document here and a helpful video tutorial here. However, understanding the purpose and significance of | may not come easily through basic examples in those resources. In my exploration of the sou ...

The issue with the `.load` function in jQuery not functioning properly

I'm currently tackling an issue with a project where I am encountering difficulties with the .load function not working in Google Chrome. Below is the JavaScript code: function link1() { $('#loadarea').html('loading.....' ...

Tips for centering a div horizontally when it exceeds the width of a mobile screen

My challenge is to create a circular div element that is wider than the mobile screen and perfectly centered. This circular div needs to be an exact circle, specifically targeted for mobile screens. I've attempted to achieve this using the code in th ...

Retrieve the quantity of files in a specific directory by implementing AJAX within a chrome extension

I need assistance with obtaining the count of images in a specific directory using JS and AJAX within my chrome extension. My current code is included below, but it does not seem to be functioning as expected since the alert is not displaying. main.js .. ...

Is there a way to minimize superfluous re-renders in React without resorting to the useMemo hook?

I am currently evaluating whether I should adjust my strategy for rendering components. My current approach heavily relies on using modals, which leads to unnecessary re-renders when toggling their visibility. Here is a general overview of how my componen ...

Encountering issues with running NPM on my Ubuntu server hosted on Digital Ocean

After successfully installing node (nodejs), I encountered a persistent error when attempting to use NPM. Despite researching the issue extensively and trying different solutions, I have been unable to resolve it. Here is the error message displayed in th ...

in Vue.js, extract the style of an element and apply it to a different element

Currently, I am using VUE.js 2 in my project. Here is my website's DOM structure: <aside :style="{height : height()}" class="col-sm-4 col-md-3 col-lg-3">...</aside> <main class="col-sm-8 col-md-9 col-lg-9" ref="userPanelMainContents" ...