用Jasmine模拟jQueryAjax调用
我使用Jasmine 2.5.2为使用jQuery3.1.1执行Ajax请求的代码编写单元测试。我想模拟Ajax调用,提供我自己的响应状态和文本 我正在使用jasmineajax插件() 遵循上的示例,它使用XMLHttpRequest对象,效果很好用Jasmine模拟jQueryAjax调用,jquery,ajax,unit-testing,jasmine,jasmine-ajax,Jquery,Ajax,Unit Testing,Jasmine,Jasmine Ajax,我使用Jasmine 2.5.2为使用jQuery3.1.1执行Ajax请求的代码编写单元测试。我想模拟Ajax调用,提供我自己的响应状态和文本 我正在使用jasmineajax插件() 遵循上的示例,它使用XMLHttpRequest对象,效果很好 describe("mocking ajax", function() { describe("suite wide usage", function() { beforeEach(function() {
describe("mocking ajax", function() {
describe("suite wide usage", function() {
beforeEach(function() {
jasmine.Ajax.install();
});
afterEach(function() {
jasmine.Ajax.uninstall();
});
it("specifying response when you need it", function() {
var doneFn = jasmine.createSpy("success");
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(args) {
if (this.readyState == this.DONE) {
doneFn(this.responseText);
}
};
xhr.open("GET", "/some/cool/url");
xhr.send();
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');
expect(doneFn).not.toHaveBeenCalled();
jasmine.Ajax.requests.mostRecent().respondWith({
"status": 200,
"contentType": 'text/plain',
"responseText": 'awesome response'
});
expect(doneFn).toHaveBeenCalledWith('awesome response');
});
});
});
注意:这与文档中的示例略有不同,必须将jasmine.Ajax.requests.mostRecent().response()
更改为jasmine.Ajax.requests.mostRecent().respondWith()
当我使用jQueryAjax时,从不调用doneFn
describe("mocking ajax", function() {
describe("suite wide usage", function() {
beforeEach(function() {
jasmine.Ajax.install();
});
afterEach(function() {
jasmine.Ajax.uninstall();
});
it("specifying response when you need it", function() {
var doneFn = jasmine.createSpy("success");
$.ajax({
method: "GET",
url: "/some/cool/url"})
.done(function(result) {
doneFn(result);
});
expect(doneFn).toHaveBeenCalledWith('awesome response');
});
});
});
茉莉花说
Jasmine Ajax在
XMLHttpRequest对象,因此应与其他
执行ajax请求的库
$.ajax从1.4.x返回一个jqXHR,而不是XMLHttpRequest-这会破坏Jasmine ajax的支持吗?以下是在Jasmine测试中模拟ajax的几种方法 方法A:
- 使用mock ajax.js,可以模拟全局xhr对象,如中所述
- 但是,您需要在success函数上指定一个spy,并让它调用(如下面的代码所示)
- 看到它在行动吗
- 直接模拟$.ajax对象。无论是get/post/load还是jquery中的任何ajax风格,您都可以简单地模拟$.ajax,如下所示
var testObj = { ajaxFunction : function(url){ $.ajax({url : url}).done(this.successFunction.bind(this)); }, successFunction : function(data){ console.log(data); } } describe('ajax test suite', function(){ it('sample test', function(){ testObj.ajaxFunction('https://jsonplaceholder.typicode.com/posts/1'); spyOn($, 'ajax').and.callFake(function(e) { return $.Deferred().resolve({'text':'this a a fake response'}).promise(); }); spyOn(testObj, 'successFunction').and.callThrough(); testObj.ajaxFunction('https://jsonplaceholder.typicode.com/posts/1'); expect(testObj.successFunction).toHaveBeenCalledWith({'text':'this a a fake response'}); }); });
spyOn($, 'ajax').and.callFake(function (options) {
var result = undefined, status, xhr;
options.success(result, status, xhr);
});
spyOn($, 'ajax').and.callFake(function (options) {
var xhr = undefined, status, error;
options.error(xhr, status, error);
});
除回答(方法B)外:
我添加了options.success(testData)
insidespyOn($,'ajax')
来触发this.processResponseData
Fn测试:
var objUnderTest = {};
objUnderTest.makeRequest(requestUrl) {
$.ajax(requestUrl)
.then(response => {
this.processResponseData(response.data[0]) // get data from first array item
})
}
测试:
你的第二种方法在这里对我有效。假代码还可以返回
$.Deferred().reject(obj)
来测试Ajax错误,其中obj有一个带有错误文本的responseText属性。@Lozzer这是正确的。使用deferred,您可以根据您的需求来解决/拒绝。如果我们有其他jQuery AJAX调用需要在测试中调用,该怎么办?我开始觉得这是唯一可行的解决方案,我对此一点也不高兴。如果我只是想模拟整个$.ajax函数,那么首先使用jasmine.ajax有什么意义呢?在第二个示例中,您从来没有为请求定义响应。。。
var objUnderTest = {};
objUnderTest.makeRequest(requestUrl) {
$.ajax(requestUrl)
.then(response => {
this.processResponseData(response.data[0]) // get data from first array item
})
}
describe('objUnderTest.makeRequest', () => {
const testData = {data: [{'text': 'this a a fake response'}]};
let processResponseData;
beforeAll(() => {
spyOn($, 'ajax').and.callFake(function (options) {
options.success(testData)
return $.Deferred().resolve(testData).promise();
});
processResponseData = spyOn(objUnderTest, 'processResponseData')
})
it('should make ajax call', () => {
objUnderTest.makeRequest({success: stockTicker.processResponseData});
expect(processResponseData).toHaveBeenCalled();
});
});