Program Club

Jasmine 및 / 또는 Sinon을 사용하여 jQuery의 .ajax () 약속을 올바르게 단위 테스트하는 방법은 무엇입니까?

proclub 2021. 1. 6. 19:59
반응형

Jasmine 및 / 또는 Sinon을 사용하여 jQuery의 .ajax () 약속을 올바르게 단위 테스트하는 방법은 무엇입니까?


jQuery .ajax () 약속을 반환하는 상당히 간단한 함수가 있습니다.

CLAW.controls.validateLocation = function(val, $inputEl) {
    return $.ajax({
        url: locationServiceUrl + 'ValidateLocation/',
        data: {
            'locationName': val
        },
        beforeSend: function() {
            $inputEl.addClass('busy');
        }
    }).done(function(result) {
        // some success clauses
    }).fail(function(result) {
        // some failure clauses
    }).always(function() {
        // some always clauses
    });
}

대부분의 경우이 새로운 promise 인터페이스는 꿈처럼 작동하며 jQuery의 .ajax ()를 사용할 때 콜백 피라미드를 제거하는 것이 좋습니다. 그러나 나는 Jasmine 및 / 또는 Sinon을 사용하여 이러한 약속을 올바르게 테스트하는 방법을 평생 알 수 없습니다.

  1. Sinon의 모든 문서는 구식 콜백을 사용하고 있다고 가정합니다. promises / deferreds와 함께 사용하는 방법에 대한 단일 예제가 없습니다.

  2. $ 아약스 감시하는 재스민이나 Sinon 스파이를 사용하려고 시도하는 경우, 스파이 효과적으로 있도록 약속을 덮어 쓰기되고 done, failalways조항은 더 이상 아약스 기능에 존재하지 않는, 약속 때문에 결코 결의를 대신 오류를 던져

앞서 언급 한 테스트 라이브러리로 이러한 새로운 jQuery .ajax () 약속을 테스트하는 방법 중 한두 가지 예를 정말 좋아할 것입니다. 나는 '그물을 상당히 강렬하게 샅샅이 뒤졌고 그렇게하는 것에 대해 아무것도 준설하지 않았다. 내가 찾은 리소스 중 하나는 Jasmine.ajax를 사용하여 언급되었지만 가능한 경우 Sinon이 동일한 기능의 대부분을 기본적으로 제공하므로이를 피하고 싶습니다.


실제로 그렇게 복잡하지 않습니다. 약속을 반환하고 귀하의 경우에 따라 해결하는 것으로 충분합니다.

예를 들면 :

spyOn($, 'ajax').andCallFake(function (req) {
    var d = $.Deferred();
    d.resolve(data_you_expect);
    return d.promise();
});

성공을 위해, 또는

spyOn($, 'ajax').andCallFake(function (req) {
    var d = $.Deferred();
    d.reject(fail_result);
    return d.promise();
});

실패를 위해.

Jasmine 2.0의 경우 구문이 약간 변경되었습니다.

spyOn($, 'ajax').and.callFake(function (req) {});

.andCallFake () 메소드가 Jasmine 2.0에 없습니다.


이 줄을 따라 / sinon 및 jQuery 지연

ajaxStub = sinon.stub($, "ajax");

function okResponse() {
  var d = $.Deferred();
  d.resolve( { username: "testuser", userid: "userid", success: true } );
  return d.promise();
};

function errorResponse() {
 var d = $.Deferred();
 d.reject({},{},"could not complete");
 return d.promise();
};

ajaxStub.returns(okResponse());
ajaxStub.returns(errorResponse());

다음은 자바 스크립트만으로 더 간단한 접근 방식입니다.

quoteSnapshots: function (symbol, streamId) {
                var FakeDeferred = function () {
                    this.error = function (fn) {
                        if (symbol.toLowerCase() === 'bad-symbol') {
                            fn({Error: 'test'});
                        }
                        return this;
                    };
                    this.data = function (fn) {
                        if (symbol.toLowerCase() !== 'bad-symbol') {
                            fn({});
                        }
                        return this;
                    };
                };

                return new FakeDeferred();
            }

The if statements inside of each callback are what I use in my test to drive a success or error execution.


The solution given by @ggozad won't work if you use things like .complete().

But, hooray, jasmine made a plugin to do exactly this: http://jasmine.github.io/2.0/ajax.html

beforeEach(function() {
  jasmine.Ajax.install();
});

afterEach(function() {
  jasmine.Ajax.uninstall();
});

//in your tests
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');

ReferenceURL : https://stackoverflow.com/questions/13148356/how-to-properly-unit-test-jquerys-ajax-promises-using-jasmine-and-or-sinon

반응형