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 테스트와 관련된 블로그 / 자료에 대한 모든 포인터는 크게 감사 할 것입니다.
답변
두 가지 유형의 테스트를 수행 할 수 있습니다.
- AJAX 요청을 위조하는 단위 테스트 (Jasmine의 스파이 사용) 를 통해 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");
이 답변 에서 언급했듯이
다음은 AJAX 요청이 성공적으로 완료되면 콜백이 실행되었는지 확인하는 유사한 단위 테스트입니다.
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
});
}
들어 2.0 재스민 사용하는 대신 :
spyOn($, "ajax").and.callFake(function(options) {
이 답변 에서 언급했듯이
마지막으로, 통합 목적을 위해 실제 AJAX 요청을 만드는 통합 테스트를 작성하고 싶다고 다른 곳에서 암시했습니다. 이것은 Jasmine의 비동기 기능인 waits (), waitsFor () 및 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
});
}
답변
jasmine-ajax 프로젝트를보십시오 : http://github.com/pivotal/jasmine-ajax .
요청이 절대 나가지 않도록 XHR 계층에서 (jQuery 또는 Prototype.js의 경우) 스텁하는 드롭 인 도우미입니다. 그런 다음 요청에 대해 원하는 모든 것을 기대할 수 있습니다.
그런 다음 모든 케이스에 대한 고정 응답을 제공 한 다음 성공, 실패, 승인되지 않은 등 원하는 각 응답에 대한 테스트를 작성할 수 있습니다.
비동기 테스트 영역에서 Ajax 호출을 가져와 실제 응답 핸들러가 작동하는 방식을 테스트 할 수있는 많은 유연성을 제공합니다.
답변
다음은 이와 같은 앱 js에 대한 간단한 예제 테스트 모음입니다.
var app = {
fire: function(url, sfn, efn) {
$.ajax({
url:url,
success:sfn,
error:efn
});
}
};
URL 정규 표현식을 기반으로 콜백을 호출하는 샘플 테스트 스위트
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();
});
});
답변
Jasmine으로 ajax 코드를 지정할 때 의존하는 함수가 원격 호출을 시작하는 모든 것을 감시하여 문제를 해결합니다 (예 : $ .get 또는 $ ajax). 그런 다음 설정된 콜백을 검색하고 개별적으로 테스트합니다.
최근에 제가 제안한 예는 다음과 같습니다.
답변
jqueryspy.com을 사용해보십시오. 테스트를 설명하는 구문과 같은 우아한 jquery를 제공하고 ajax가 완료된 후 콜백을 테스트 할 수 있습니다. 통합 테스트에 적합하며 최대 아약스 대기 시간을 초 또는 밀리 초 단위로 구성 할 수 있습니다.
답변
Jasmine이 현재 버전 2.4이고 버전 2.0에서 몇 가지 기능이 변경되었으므로 더 최신 답변을 제공해야한다고 생각합니다.
따라서 AJAX 요청 내에서 콜백 함수가 호출되었는지 확인하려면 스파이를 만들고 callFake 함수를 추가 한 다음 스파이를 콜백 함수로 사용해야합니다. 방법은 다음과 같습니다.
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
});
});
});
AJAX가 오류를 반환하더라도 Jasmine이 가능한 한 빨리 사양을 실행할 수 있도록 성공 함수와 오류 함수에 대한 트릭을 수행했습니다.
오류 함수를 지정하지 않고 AJAX가 오류를 반환하면 Jasmine에서 오류가 발생할 때까지 5 초 (기본 시간 제한 간격)를 기다려야합니다 Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
. 다음과 같이 고유 한 시간 제한을 지정할 수도 있습니다.
it("should get the content of an XML file", function(done)
{
// your code
},
10000); // 10 seconds