Jasmine으로 jQuery AJAX 이벤트를 어떻게 확인합니까?
Jasmine을 사용하여 기본 jQuery AJAX 요청에 대한 일부 BDD 사양을 작성하려고합니다. 현재 Jasmine을 독립형 모드 (예 : ~ SpecRunner.html)로 사용하고 있습니다. jQuery 및 기타 .js 파일을로드하도록 SpecRunner를 구성했습니다. 다음이 작동하지 않는 이유가 있습니까? has_returned는 사실이 아니며, "yuppi!" 경고가 잘 나타납니다.
describe("A jQuery ajax request should be able to fetch...", function() {
it("an XML file from the filesystem", function() {
$.ajax_get_xml_request = { has_returned : false };
// initiating the AJAX request
$.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",
success: function(xml) { alert("yuppi!"); $.ajax_get_xml_request.has_returned = true; } });
// waiting for has_returned to become true (timeout: 3s)
waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "the JQuery AJAX GET to return", 3000);
// TODO: other tests might check size of XML file, whether it is valid XML
expect($.ajax_get_xml_request.has_returned).toEqual(true);
});
});
콜백이 호출되었는지 어떻게 테스트합니까? Jasmine으로 비동기 jQuery를 테스트하는 것과 관련된 블로그 / 자료에 대한 조언은 크게 감사하겠습니다.
두 가지 유형의 테스트가 가능하다고 생각합니다.
- Jasmine의 스파이를 사용하여 AJAX 요청을 위조하는 단위 테스트를 통해 AJAX 요청 직전 과 직후에 실행되는 모든 코드를 테스트 할 수 있습니다 . Jasmine을 사용하여 서버에서 응답을 속일 수도 있습니다. 실제 AJAX가 진행되지 않기 때문에 이러한 테스트는 더 빠르며 비동기 동작을 처리 할 필요가 없습니다.
- 실제 AJAX 요청을 수행하는 통합 테스트. 이들은 비동기식이어야합니다.
Jasmine은 두 종류의 테스트를 모두 도와줍니다.
다음은 AJAX 요청을 위조 한 다음 위조 된 AJAX 요청이 올바른 URL로 가고 있는지 확인하기 위해 단위 테스트를 작성하는 방법에 대한 샘플입니다.
it("should make an AJAX request to the correct URL", function() {
spyOn($, "ajax");
getProduct(123);
expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");
});
function getProduct(id) {
$.ajax({
type: "GET",
url: "/products/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json"
});
}
들어 2.0 재스민 사용하는 대신 :
expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");
이 답변에 명시된 바와 같이
Here is a similar unit test that verifies your callback was executed, upon an AJAX request completing successfully:
it("should execute the callback function on success", function () {
spyOn($, "ajax").andCallFake(function(options) {
options.success();
});
var callback = jasmine.createSpy();
getProduct(123, callback);
expect(callback).toHaveBeenCalled();
});
function getProduct(id, callback) {
$.ajax({
type: "GET",
url: "/products/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: callback
});
}
For Jasmine 2.0 use instead:
spyOn($, "ajax").and.callFake(function(options) {
as noted in this answer
Finally, you have hinted elsewhere that you might want to write integration tests that make real AJAX requests - for integration purposes. This can be done using Jasmine's asyncronous features: waits(), waitsFor() and runs():
it("should make a real AJAX request", function () {
var callback = jasmine.createSpy();
getProduct(123, callback);
waitsFor(function() {
return callback.callCount > 0;
});
runs(function() {
expect(callback).toHaveBeenCalled();
});
});
function getProduct(id, callback) {
$.ajax({
type: "GET",
url: "data.json",
contentType: "application/json; charset=utf-8"
dataType: "json",
success: callback
});
}
Look at the jasmine-ajax project: http://github.com/pivotal/jasmine-ajax.
It's a drop-in helper that (for either jQuery or Prototype.js) stubs at the XHR layer so that requests never go out. You can then expect all you want about the request.
Then it lets you provide fixture responses for all your cases and then write tests for each response that you want: success, failure, unauthorized, etc.
It takes Ajax calls out of the realm of asynchronous tests and provides you a lot of flexibility for testing how your actual response handlers should work.
here is a simple example test suite for an app js like this
var app = {
fire: function(url, sfn, efn) {
$.ajax({
url:url,
success:sfn,
error:efn
});
}
};
a sample test suite, which will call callback based on url regexp
describe("ajax calls returns", function() {
var successFn, errorFn;
beforeEach(function () {
successFn = jasmine.createSpy("successFn");
errorFn = jasmine.createSpy("errorFn");
jQuery.ajax = spyOn(jQuery, "ajax").andCallFake(
function (options) {
if(/.*success.*/.test(options.url)) {
options.success();
} else {
options.error();
}
}
);
});
it("success", function () {
app.fire("success/url", successFn, errorFn);
expect(successFn).toHaveBeenCalled();
});
it("error response", function () {
app.fire("error/url", successFn, errorFn);
expect(errorFn).toHaveBeenCalled();
});
});
When I specify ajax code with Jasmine, I solve the problem by spying on whatever depended-on function initiates the remote call (like, say, $.get or $ajax). Then I retrieve the callbacks set on it and test them discretely.
Here's an example I gisted recently:
https://gist.github.com/946704
Try jqueryspy.com It provides an elegant jquery like syntax to describe your tests and allows callbacks to test after the ajax has complete. Its great for integration testing and you can configure maximum ajax wait times in seconds or milleseconds.
I feel like I need to provide a more up-to-date answer since Jasmine is now at version 2.4 and a few functions have changed from the version 2.0.
So, to verify that a callback function has been called within your AJAX request, you need to create a spy, add a callFake function to it then use the spy as your callback function. Here's how it goes:
describe("when you make a jQuery AJAX request", function()
{
it("should get the content of an XML file", function(done)
{
var success = jasmine.createSpy('success');
var error = jasmine.createSpy('error');
success.and.callFake(function(xml_content)
{
expect(success).toHaveBeenCalled();
// you can even do more tests with xml_content which is
// the data returned by the success function of your AJAX call
done(); // we're done, Jasmine can run the specs now
});
error.and.callFake(function()
{
// this will fail since success has not been called
expect(success).toHaveBeenCalled();
// If you are happy about the fact that error has been called,
// don't make it fail by using expect(error).toHaveBeenCalled();
done(); // we're done
});
jQuery.ajax({
type : "GET",
url : "addressbook_files/addressbookxml.xml",
dataType : "xml",
success : success,
error : error
});
});
});
I've done the trick for the success function as well as the error function to make sure that Jasmine will run the specs as soon as possible even if your AJAX returns an error.
If you don't specify an error function and your AJAX returns an error, you will have to wait 5 seconds (default timeout interval) until Jasmine throws an error Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.. You can also specify your own timeout like this:
it("should get the content of an XML file", function(done)
{
// your code
},
10000); // 10 seconds
참고URL : https://stackoverflow.com/questions/4662641/how-do-i-verify-jquery-ajax-events-with-jasmine
'Programing' 카테고리의 다른 글
| awk / sed로 여러 번 나타날 수있는 두 마커 패턴 사이에서 선을 선택하는 방법 (0) | 2020.07.25 |
|---|---|
| Order By가있는 SQL Group By (0) | 2020.07.25 |
| React에서 변수와 문자열 연결 (0) | 2020.07.25 |
| UIPickerView 높이를 변경하는 방법 (0) | 2020.07.25 |
| Rails 앱이 사용하는 gem 버전을 확인하는 방법 (0) | 2020.07.25 |