【问题标题】:Jasmine, Unit testing XMLHttpRequest with PromisesJasmine,使用 Promises 对 XMLHttpRequest 进行单元测试
【发布时间】:2016-11-03 13:30:04
【问题描述】:

我有以下使用 Q Promise 库的函数

getConfig: function(params){

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

上面的代码调用了如下所示的API代码(为了去噪,我把代码缩写了)

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));
          }
      };
}

我的问题是:如何为 getConfig 编写 Jasmine 测试,即伪造响应并存根底层 XMLHttpRequest ? sinon.js 能做到这一点吗?我知道它可以在 $.ajax 上存根回调,但我不确定如何使用诸如 Q 之类的 Promise 库来执行此操作。请注意,这是纯 JavaScript,没有角度等

【问题讨论】:

    标签: javascript jasmine sinon


    【解决方案1】:
    • 这里是如何在 jasmine 中使用 callFake 来返回一个承诺。
    • 现在由于 Q 和传统的 jQuery 都提供了延迟 对象,您可以将 $.Deferred() 替换为 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
        });

    【讨论】:

    • 您的示例给出了一个错误:错误::get() 方法不存在用法:spyOn(, ) in node_modules/jasmine-core/lib/jasmine- core/jasmine.js(第 2075 行)
    • 我现在对这个答案冬兵投了赞成票。将他的答案重构为我的实际代码后,我现在有了一个带有完整模拟等的工作单元测试。干杯 Winter Soldier :-)
    • 我很高兴能帮助你@Rory。顺便编辑了答案以消除错误。感谢您的投票。
    【解决方案2】:

    如果有人感兴趣,这是我的 Jasmine 测试,希望对您有所帮助

    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();
            });
    
        });
    });
    

    【讨论】:

      猜你喜欢
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 2017-02-28
      相关资源
      最近更新 更多