简体   繁体   中英

Jasmine, Unit testing XMLHttpRequest with Promises

I have the following function, that uses the Q promise library

getConfig: function(params){

            return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){
                return response;
            }, function(err){
                throw err;
            });
        }

The above code calls the API code shown below (I've abbreviated the code to rid noise)

CodeApiClient.prototype = {
  get: function(endpoint, paramStr, headers){
      var defer = new Q.defer();
      var start_time = new Date().getTime();

      var req = new XMLHttpRequest();
      var url = endpoint + (paramStr.indexOf('?') !== -1 ? paramStr : '?' + paramStr);

      req.open('GET', url);

      req.onload = function() {
          var request_time = new Date().getTime() - start_time;
          // This is called even on 404 etc
          if (req.status < 400) {
              var response = JSON.parse(req.response)
              response.__request_time = request_time;
              defer.resolve(response);
          } else {
              // Otherwise reject with the status text
              defer.reject(Error(req.statusText));
          }
      };
}

My question is: How do I write a Jasmine test for getConfig ie faking the response and stubbing the underlying XMLHttpRequest ? Is sinon.js capable of this. I know it can stub callbacks on $.ajax, but I'm not sure how to do this with a promise lib such as Q. Note this is pure JavaScript, no angular etc

  • Here is how to use callFake in jasmine to return a promise.
  • Now since both Q as well as traditional jQuery provide the deferred objects, you could substitute $.Deferred() with Q.defer();

 var tempObj = { getConfig: function(params){ return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){ return response; }, function(err){ throw err; }); } codeApiClient : { get : function(){ // some get function of codeApiClient } } } it('test getConfig success', function(){ var dummyResponse = {'someDummyKey' : 'someDummyValue'}; spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){ return $.Deferred().resolve(dummyResponse).promise(); }); tempObj.getConfig({}); //any expectations }); it('test getConfig failure', function(){ var dummyResponse = {'error' : 'someDummyFailure'}; spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){ return $.Deferred().reject(dummyResponse).promise(); }); tempObj.getConfig({}); //any expectations }); 

If anyone is interested here's my Jasmine test, hope it helps

define([ 'q', 'lodash', 'jquery',  'ChatApi'], function (Q, _ , $ ,  ChatApi) {

    describe('Chat Api test', function () {
        var categories
        var chatApi;
        var fakeResponse;

        beforeEach(function() {
            //fakes
             categories = {
                "l10n": {
                    "defaultLanguage": "en-GB",
                    "languages": [
                        {
                            "name": "en-GB",
                            "value": "Tell me more..."
                        },
                        {
                            "name": "fr",
                            "value": "On veut tout savoir..."
                        },
                        {
                            "name": "de",
                            "value": "Wähle die passende Kategorie aus..."
                        }
                    ]
                }
            };
            fakeResponse = {
                'categories': categories
            }
            chatApi = new ChatApi("https://server/gateway/","v1");
        });

        it('test getConfig success', function(done){
            var getConfigCalled = spyOn(chatApi, 'getConfig').and.callFake(function(e){
                //jQuery version of promises
               //return $.Deferred().resolve(fakeResponse).promise();
                var deferred = Q.defer();
                deferred.resolve(fakeResponse);
                return deferred.promise;
            });

            chatApi.getConfig({}).then(function(response){
                //compare objects using lodash
                var x = _.isEqual(response.categories, fakeResponse.categories);
                expect(x).toBe(true);
            })

            expect(getConfigCalled).toHaveBeenCalled();

            done();
        });

    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM