2015-08-31 5 views
3

Я создаю модуль XMLHttpRequest javascript для получения данных JSON с сервера. Вот код:правильное использование поддельного синона XMLHttpRequest

(function() { 
    var makeRequest = function(url,callback,opt) { 
    var xhr; 
    if (XMLHttpRequest) { // Mozilla, Safari, ... 
     xhr = new XMLHttpRequest(); 
    } else if (ActiveXObject) { // IE 
     try { 
     xhr = new ActiveXObject("Msxml2.XMLHTTP"); 
     } 
     catch (e) { 
     try { 
      xhr = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     catch (e) {} 
     } 
    } 

    if (!xhr) { 
     callback.call(this, 
     'Giving up :(Cannot create an XMLHTTP instance', 
     null); 
     return false; 
    } 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState === 4) { 
     if (xhr.status === 200) { 
      var data = xhr.responseText; 
      if(opt && !opt.raw) { 
      try { 
       data = JSON.parse(data); 
      } catch (e) { 
       callback.call(this, e,null); 
       return; 
      } 
      } 
      callback.call(this,null,data); 
     } else { 
      callback.call(this, 
      'There was a problem with the request.', 
      null); 
     } 
     } 
    }; 
    var params = ''; 
    if (opt && opt.params && typeof(opt.params) == 'object') { 
     for(var key in opt.params) { 
     params += encodeURIComponent(opt.params[key]); 
     } 
    } 
    var method = opt && opt.method ? opt.method : 'GET'; 
    if (method == 'GET') { 
     url = params.length > 0 ? url+'?'+params : url; 
     xhr.open('GET', url); 
     xhr.send(); 
    } else if (method == 'POST') { 
     var data = opt && opt.data ? opt.data : params; 
     xhr.open('POST', url); 
     xhr.send(JSON.stringify(data)); 
    } 
    return xhr; 
    } 

    if(typeof module !== 'undefined' && module.exports) { 
    module.exports = makeRequest; 
    } 
    if(typeof window!== 'undefined') { 
    window.getJSONData = makeRequest; 
    } 
})(); 

Сейчас я пишу тест, для этого на nodejs с мокко и Синоном. Использование fakeXMLHttpRequest Синона для тестирования модуля и тестированию коды здесь:

var expect = require('chai').expect, 
    getJSON = require('../'), 
    sinon = require('sinon'); 

describe('get-json-data test the request', function() { 
    beforeEach(function() { 
    this.xhr = sinon.useFakeXMLHttpRequest(); 
    var requests = this.requests = []; 

    this.xhr.onCreate = function (xhr) { 
     requests.push(xhr); 
    }; 
    }); 
    afterEach(function() { 
    this.xhr.restore(); 
    }); 

    it('get json data', function() { 
    var callback = sinon.spy(); 
    getJSON('/some/json', callback); 
    expect(this.requests.length).to.equal(1); 
    this.requests[0].respond(200, 
     {"Content-Type": "application/json"}, 
     '{"id": 1, "name": "foo"}'); 
    sinon.assert.calledWith(callback, {"id": 1, "name": "foo"}); 
    }); 
}); 

На запуске теста я получаю ошибку:

ReferenceError: XMLHttpRequest is not defined

И это кажется правильным, поскольку нет никакого класса XMLHttpRequest/функции nodejs. Но FakeXMLHttpRequest от Sinon не должен этого делать. Я думал, что в Sinon's setUp (Mocha's beforeEach) мы заменяем собственный XMLHttpRequest fakeXMLHttpRequest. Пожалуйста, предложите, что я делаю неправильно? Или что было бы правильным способом проверить мой модуль на узлах?

ответ

8

Поскольку вы работаете за пределами среды браузера, нет объекта XMLHttpRequest. Поскольку вы издеваетесь над Sinon, что вы можете сделать, это объявить фальшивую глобальную функцию в вашем вызове beforeEach.

global.XMLHttpRequest = sinon.useFakeXMLHttpRequest(); 
+0

Благодаря @yashua это решить мою проблему. – Gagan

+0

Да, я тестирую среду node.js. Но с вами намек, что это работает. Спасибо @yashua. – Reinhard

0

Я сделал это для подмены XMLHttpRequest (см мой вопрос и ответ here):

var FakeXMLHTTPRequests = require('fakexmlhttprequest') 
var requests = [] 

XMLHttpRequest = function() { 
    var r = new FakeXMLHTTPRequests(arguments) 
    requests.push(r) 
    return r 
} 
+0

Спасибо @ timhc22 за обновление, прямо сейчас я использую Sinon, поэтому использование SinonFakeXMLHttpRequest отлично работает для меня. – Gagan

+0

потрясающий! может попробовать это в какой-то момент – timhc22

Смежные вопросы