Results 1 to 5 of 5

Thread: Preferred way to mock Ajax requests for local browser testing

  1. #1
    Sencha Premium User
    Join Date
    Jan 2009
    Posts
    449
    Answers
    19
    Vote Rating
    243
      0  

    Default Answered: Preferred way to mock Ajax requests for local browser testing

    I have an API of REST services running on a server. I'm developing an app in Sencha Architect that accesses these services. The services are authenticated, so CORS is an issue for me. I don't much want to alter the server that hosts the REST services as this is only an issue in development (the built app will be hosted on the same server as the REST services). For previewing in Sencha Architect, it's simple enough to disable security in the browsers so the request goes through ok .

    I'm evaluating Sencha Test for unit testing components for this app and am wondering how to accommodate this.

    First question - Is there any built-in way in Sencha Test to have a proxy server that forwards the actual requests to bypass this issue?

    I've also considered that in a unit testing scenario, it might not be advisable to depend on external resources anyway and I should try and use some mock test data.

    Second question - What is the preferred way of mocking Ajax requests in Sencha Test?

    I've seen the Ext.ux.ajax.SimManager, but this is problematic because it doesn't appear to be included with the rest of the Ext source by default. I had to copy the ux folder manually into the src folder for the app and then require it on every component I want to test. Is there an easier way to reference it in the tests or does the ST API have something I'm not aware of?

    I don't have much experience with Jasmine, but I think it has built-in spy methods that could potentially work, too. Is there one solution that is superior out of the SimManager vs Jasmine spy methods?

  2. Sencha Test proxies the app (when using the In-Browser mechanism), so you can make additional requests for resources within that same site, and they will be passed through. However, you will likely run in to issues if the web services are on a different endpoint that requires authentication, which sounds like the case here. In that instance, you would need to call those endpoints directly, which will need additional CORS rules (e.g. to allow requests from the Sencha Test proxied URL), and perhaps authenticate using a token.

    Alternatively, it is possible to mock Ajax requests using the SimManager. I have included an example below.

    First, in your project's "app.json" under the "development" section, add a "requires" section specifically for the development build and add the "ux" package. For example:


    Code:
        "development": {
            "watch": {
                "delay": 250
            },
            "tests": {
                "path": "test/project.json"
            },
            "requires": [
                "ux"
            ]
        },
    Then, in your test suite do an "Ext.require" of the "Ext.ux.ajax" classes using Jasmine's "beforeAll". This will load the SimManager (and related classes) prior to the tests being run. After these classes have been loaded, the SimManager can be initialized and the endpoints configured. When an Ajax request is made to one of the endpoints, the mock data will be returned:

    Code:
    describe('Data Tests', function() {
        beforeAll(function(done) {
            Ext.require('Ext.ux.ajax.*', function() {
                Ext.ux.ajax.SimManager.init({
                    delay: 300
                }).register({
                    '/users': {
                        type: 'json',
                        data: [{ 
                            id: 1, 
                            name: 'Dan'
                        }, {
                            id: 2,
                            name: 'Dave'
                        }]
                    }
                });
                
                done();
            });
        });
        
        it('should load a mock set of users', function(done) {
            Ext.Ajax.request({
                url: '/users',
                success: function(response) {
                    // Validate response here
    
    
                    done();
                }
            });
        });
    });
    I tested the above example on an Ext JS 6.6 Classic app.

    Hope this helps.

  3. #2
    Sencha Premium User
    Join Date
    Jan 2009
    Posts
    449
    Answers
    19
    Vote Rating
    243
      0  

    Default

    Even though I can load Ext.ux.ajax.SimManager, I couldn't actually get it working, whether in a local browser test or just from within Architect. The ajax calls are still executed. Could someone please confirm if this class still works in Ext 6.6?

    I don't have a solution right now; any help with a complete example of mocking Ajax requests in Sencha Test would be much appreciated.

  4. #3
    Sencha - Sales Team daniel.gallo's Avatar
    Join Date
    Apr 2009
    Location
    Redwood City, CA
    Posts
    280
    Answers
    38
    Vote Rating
    35
      1  

    Default

    Sencha Test proxies the app (when using the In-Browser mechanism), so you can make additional requests for resources within that same site, and they will be passed through. However, you will likely run in to issues if the web services are on a different endpoint that requires authentication, which sounds like the case here. In that instance, you would need to call those endpoints directly, which will need additional CORS rules (e.g. to allow requests from the Sencha Test proxied URL), and perhaps authenticate using a token.

    Alternatively, it is possible to mock Ajax requests using the SimManager. I have included an example below.

    First, in your project's "app.json" under the "development" section, add a "requires" section specifically for the development build and add the "ux" package. For example:


    Code:
        "development": {
            "watch": {
                "delay": 250
            },
            "tests": {
                "path": "test/project.json"
            },
            "requires": [
                "ux"
            ]
        },
    Then, in your test suite do an "Ext.require" of the "Ext.ux.ajax" classes using Jasmine's "beforeAll". This will load the SimManager (and related classes) prior to the tests being run. After these classes have been loaded, the SimManager can be initialized and the endpoints configured. When an Ajax request is made to one of the endpoints, the mock data will be returned:

    Code:
    describe('Data Tests', function() {
        beforeAll(function(done) {
            Ext.require('Ext.ux.ajax.*', function() {
                Ext.ux.ajax.SimManager.init({
                    delay: 300
                }).register({
                    '/users': {
                        type: 'json',
                        data: [{ 
                            id: 1, 
                            name: 'Dan'
                        }, {
                            id: 2,
                            name: 'Dave'
                        }]
                    }
                });
                
                done();
            });
        });
        
        it('should load a mock set of users', function(done) {
            Ext.Ajax.request({
                url: '/users',
                success: function(response) {
                    // Validate response here
    
    
                    done();
                }
            });
        });
    });
    I tested the above example on an Ext JS 6.6 Classic app.

    Hope this helps.
    Daniel Gallo
    Senior Solutions Architect
    Sencha Inc.

  5. #4
    Sencha Premium User
    Join Date
    Jan 2009
    Posts
    449
    Answers
    19
    Vote Rating
    243
      0  

    Default

    Thanks for following up with the detailed example - it was very helpful.

    I think some of my frustrations stemmed from either Sencha Architect or Cmd. I'm trying to test a project that I started in Sencha Architect as Ext classic 6.6. For some reason, the ux folder I was looking at under the folder structure had an old version of the SimManager and related files that would no longer work with 6.6. In particular, they used Ext.data.Connection.override instead of Ext.data.request.Ajax.override. I noticed this when trying to look at the source code from the 6.6 docs to debug the issues. Not sure how this happened, but it might be an Architect issue; haven't started a fresh project to see what I get.

    I have the SimManager method working now, through with some limitations. The success methods must be called in a different scope because some things I was trying in them like getting view model attributes don't work, but I can understand if this is just an issue with simulating requests, at least the basic functionality is working now and I can structure the app accordingly to make it easier to test.

  6. #5
    Sencha Premium User
    Join Date
    Jan 2009
    Posts
    449
    Answers
    19
    Vote Rating
    243
      0  

    Default

    Out of curiosity, I created a new blank project in Architect. Two SimManager.js files are created.

    MyProject\ext\packages\ux\src\ajax\SimManager.js
    MyProject\ext\packages\core\test\resources\ux\ajax\SimManager.js

    The one under core\test\resources is the old one that I mistakenly tried to reference. Not sure what this one is for, but I'll remember to avoid it now.

Similar Threads

  1. AJAX Requests behaves differently in Browser and Emulator
    By sbk099 in forum Sencha Touch 2.x: Q&A
    Replies: 6
    Last Post: 1 May 2014, 8:02 PM
  2. Managing HTTP Requests on Stores, TreeLoaders and Ajax Requests
    By j-joey in forum Ext 3.x: Help & Discussion
    Replies: 2
    Last Post: 14 Jun 2010, 11:32 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •