2012-02-24 3 views
6

우리는 JS 무거운 웹 응용 프로그램에 대해 QUnit JavaScript 테스트를 구현하려고합니다. 우리는 jQuery AJAX 요청과 관련된 메소드를 성공적으로 테스트하는 방법을 찾기 위해 고심하고있다. 우리는 바람직 대신 실제 someURL.php의 스텁 URL과 함께 fire 방법을 테스트 할 수있는 방법을 찾기 위해 노력하고있다QUnit을 이용한 AJAX 요청 단위 테스트

var X = function() { 
    this.fire = function() { 
     $.ajax("someURL.php", { 
      data: { 
       userId: "james" 
      }, 
      dataType: "json", 
      success: function(data) { 
       //Do stuff 
      } 
     }); 
    }; 
}; 
var myX = new X(); 
myX.fire(); 

: 예를 들어, 우리는 다음과 같은 생성자 함수 (분명히 이것은 매우 간단한 예입니다)가 있습니다.

현재 유일한 해결책은 생성자 함수에 대한 인수로 URL과 success 콜백을 추가하는 것입니다. 그렇게하면 테스트에서 X의 새 인스턴스를 만들고 스텁 URL을 전달하고 스텁이 응답을 반환 할 때 실행할 콜백을 생성 할 수 있습니다. 예 :

test("Test AJAX function", function() { 
    stop(); 
    var myX = new X(); 
    //Call the AJAX function, passing in the stub URL and success callback 
    myX.fire("stub.php", function(data) { 
     console.log(data); 
     start(); 
    }); 
}); 

그러나이 방법은 매우 좋은 해결책이 아닙니다. 더 좋은 방법이 있습니까? jQuery로

답변

9

, 당신은 약속으로 .ajax() 반환, 그래서 당신은 당신이 옵션에서 정의 단지 하나의 success, completeerror 것보다 (아래 참조) 더 처리기를 추가 할 수있는 XHR 객체를 사용할 수 있습니다. 따라서 비동기 함수가 xhr 객체를 반환 할 수 있다면 테스트 관련 핸들러를 추가 할 수 있습니다.

URL은 다소 까다 롭습니다. 필자는 종종 localhost에 아주 간단한 노드 서버를 설치했습니다.이 서버는 실제 서버에서 복사 된 미리 준비된 응답을 제공합니다. 동일한 서버에서 테스트 스위트를 실행하는 경우 URL은 프로덕션 서버 대신 테스트 서버에 도달하기위한 절대 경로 여야합니다. 또한 서버가 볼 때 요청 자체에 대한 기록을 얻습니다. 또는 테스트 서버가 코드를 처리하는 방법을보고 싶다면 의도적으로 오류 또는 잘못된 응답을 보내도록 할 수 있습니다.

하지만 꽤 복잡한 솔루션입니다. URL을 테스트 스위트에서 다시 정의 할 수있는 위치에 쉽게 정의 할 수 있습니다. 예를 들어 :

/* in your code */ 
var X = function() { 
    this.fire = function() { 
     return $.ajax({ url: this.constructor.url, ... }); 
    }; 
}; 
X.url = "someURL.php"; // the production url 

/* in your tests */ 
X.url = "stub.php"; // redefine to the test url 

또한, QUnit 당신을 위해 stop()를 호출하는 asyncTest 기능을 가지고 있습니다. 작은 헬퍼를 추가하여 언제 다시 시작해야하는지 추적하고 꽤 좋은 해결책을 얻었습니다.

는 여기에 내가 기본적으로

// create a function that counts down to `start()` 
function createAsyncCounter(count) { 
    count = count || 1; // count defaults to 1 
    return function() { --count || start(); }; 
} 

// .... 

// an async test that expects 2 assertions 
asyncTest("testing something asynchronous", 2, function() { 
    var countDown = createAsyncCounter(1), // the number of async calls in this test 
     x = new X; 

    // A `done` callback is the same as adding a `success` handler 
    // in the ajax options. It's called after the "real" success handler. 
    // I'm assuming here, that `fire()` returns the xhr object 
    x.fire().done(function(data, status, jqXHR) { 
     ok(data.ok); 
     equal(data.value, "foobar"); 
    }).always(countDown); // call `countDown` regardless of success/error 
}); 

countDown 전에 어떤에서 사용자가 지정한 다운 제로 카운트 한 다음 start()를 호출하는 기능입니다 무슨 짓을했는지입니다. 이 경우 1 개의 비동기 호출이 있으므로 countDown은 그 것으로부터 카운트 다운됩니다. 아약스 호출이 완료되면 호출 방법이 무엇이든 상관없이 콜백을 수행하므로 콜백을 always으로 설정합니다.
asyncTest에 2 개의 어설 션이 필요하다고 알려지기 때문에 .done() 콜백이 호출되지 않으면 어설 션이 실행되지 않으므로 오류가보고됩니다. 따라서 호출이 완전히 실패하면 알게 될 것입니다. 오류가 발생하여 로그를 남기고 싶다면 promise chain에 .fail() 콜백을 추가하면됩니다.

+0

이것은 훌륭합니다. 고맙습니다 :) –

2

jQuery spy을 사용해보세요. jQuery 익숙한 구문을 사용하여 아약스를 테스트하는 쉬운 방법을 만들었습니다.

Check this link

3

은 (그리고해야)는 서버 측에서 분리하여 실행할 수있는 단위 테스트가 있다면, 당신은 단순히 어떤 동작을 시뮬레이션 할 수 $.ajax을 "대체"할 수 있습니다. 하나 쉬운 예 : 때문에, 당신은하지 복잡한 반응이있는 경우

// Simulate a successfully response 
$.ajax = function(url, opts) { 
    opts.success = function(data) { 
    console.log(data); 
    start(); 
    } 
    _real_ajax('stub.php', opts) 
} 

, 나는 첫 번째 방법을 선호 :

test("Test AJAX function", function() { 
    // keep the real $.ajax 
    var _real_ajax = $.ajax; 

    // Simulate a successful response 
    $.ajax = function(url, opts) { 
    opts.success({expected: 'response'}); 
    } 

    var myX = new X(); 
    // Call your ajax function 
    myX.fire(); 
    // ... and perform your tests 

    // Don't forgot to restore $.ajax! 
    $.ajax = _real_ajax; 
}); 

분명히 당신은 또한 스텁 URL/데이터로 실제 Ajax 호출을 수행 할 수 있습니다 이해가 더 빠르고 쉽습니다.
그러나 다른 방법으로 Ajax 논리를 자체 메소드에 넣을 수 있으므로 테스트 중에 쉽게 스텁 할 수 있습니다.

+0

서버 측에서 테스트를 분리하기 위해이 라이브러리에서 많은 성공을 거뒀습니다. https://github.com/jakerella/jquery-mockjax –

관련 문제