2015-02-03 8 views
1

나는 sinn과 함께 QUnit을 사용합니다. sinone의 fakeserver을 동일한 방법으로 만든 체인 아약스에 어떻게 응답 할 수 있습니까?Sinonjs fakeerver - 여러 아약스 호출

module('demo', { 
    beforeEach: function(){ 
     this.server = sinon.fakeServer.create(); 
    }, 
    afterEach: function(){ 
     this.server.restore(); 
    } 
}); 

test('chained ajax calls', function(assert){ 

    this.server.respondWith('GET', '/foo', [200, 
    { 'Content-Type': 'application/json' }, '{ "foo": 1 }' ]); 

    this.server.respondWith('GET', '/bar', [200, 
    { 'Content-Type': 'application/json' }, '{ "bar": 1 }' ]); 

    var successCount = 0; 

    $.get('/foo', function(data){ 
     successCount++; 
     $.get('/bar', function(){ 
      console.log('bar success'); 
      successCount++; 
     }); 
    }); 

    this.server.respond(); 
    assert.strictEqual(successCount, 2); 
}); 

위의 문제점은 위의 방법 중 하나에서만 응답을 얻을 수 있다는 것입니다. fakeerver가이 문제를 처리 할 수 ​​있습니까?

업데이트 :server.respond()을 추가하면 문제가 해결됩니다. 그러나 더 좋은 방법이 있어야합니다, 그렇죠?

server.respond();

워드 프로세서에 따르면, 하나의 호출과 같은해야 작업에 관계없이 아약스 호출 횟수의 소리 대기중인 비동기 요청이 모두 응답을 받도록합니다.

는 바이올린 : http://jsfiddle.net/3qj20r5m/1/

답변

3

흠, 나는 server.repond()이뿐만 아니라 그렇게 할 줄 알았는데. 어쨌든 나는 대개 자동 응답 대신 위조 된 서버를 설정합니다. 이는 것 같다 응답하기 전에 요청을 검사 할 필요가없는 한 쉽게 : 두 번 respond()를 호출해야하는 이유

var server; 
QUnit.module('fake server tests', { 
    beforeEach: function() { 
     server = sinon.fakeServer.create(); 

     // *** it's this option I'm referring to... 
     server.autoRespond = true; 

     server.respondWith('GET', '/foo', [200, { 
      'Content-Type': 'application/json', 
      '{ "foo": 1 }' 
     }]); 

     server.respondWith('GET', '/bar', [200, { 
      'Content-Type': 'application/json', 
      '{ "bar": 1 }' 
     }]); 
    }, 
    afterEach: function() { 
     server.restore(); 
    } 
}); 

QUnit.test('do some ajax', function(assert) { 
    var done = assert.async(); 

    doTwoAjaxCalls(function() { 

     // whatever your assertions are... 
     // (of course, your method would need to perform the callback...) 

     done(); 
    }); 
}); 

UPDATE

업데이트 된 코드를 보면 우리는 볼 수 있습니다 : 첫 번째 전화가 응답 " 대기열에서 첫 번째 Ajax 요청 (/foo)을 해제 한 다음 첫 번째 성공 콜백을 호출합니다. 콜백 내에서 두 번째 아약스 호출을 시작합니다. Sinon은 respond()에 다시 전화 할 때까지 기다립니다.

다른 말로하면, respond()을 호출하면 Sinon이 현재 보유한 모든 Ajax 요청을 릴리스하게되지만, 귀하의 경우에는 한 번에 하나만 보유하게됩니다. 위에서 언급 한 autoRespond 옵션을 사용하면 Sinon이 즉시 응답하므로이 필요성이 없어지지만이 경우 비동기 테스트를 수행해야한다고 생각합니다 (또는 적어도 모범 사례 임).

행운을 빈다.

+0

오, 나는 가짜 호출이 동기식으로 실행되었다고 생각했기 때문에'assert.async'를 사용하지 않았습니다. 동기식으로 호출을 실행하는 방법이 있습니까? – filur

+0

정교하게 설명하자면, 단일 AJAX 호출이있는 모든 샘플에서 QUINIT를 중지하지 않고 응답을 기다릴 수있는 것처럼 보입니다 (예 : http://www.kenpowers.net/blog/advanced-features-in-sinon/ " '단언, 단언을 다시하십시오. 모든 것이 동기입니다. '). 그러나 위와 같이 중첩 된 호출을 사용하면 QUnit을 대기시켜야하는 것처럼 보입니다. – filur

+0

예제를 실제 코드에 가깝도록 업데이트했습니다. 호출은 실제로 중첩됩니다. 아마도 그것이 문제일까요? – filur

3

Sinon docs는 autoRespond이 비동기 적으로 실행되므로 테스트에 적합하지 않다고 말합니다. 기본값은 10ms 후로, 이는 다음 실행 프레임에 부딪 치기에 충분하며 잠재적으로 테스트를 통해 몇 가지 경쟁 상태를 유발할 수 있습니다. 내가 테스트하고 싶었던 유사한 중첩 된 AJAX 호출을했기 때문에 이것을 발견했습니다.

모든 요청에 ​​동 기적으로 응답하는 fakeServerrespondImmediately 속성을 구현했습니다. 몇 주 전에 프로젝트에 병합되었습니다 (v1.14.0). 그러나 최신 버전으로 업데이트하면 얻을 수 있습니다. Check out the docs here..

autoRespond 속성을 true로 설정하는 대신 beforeEach 블록에서 respondImmediately 속성을 true로 설정하십시오. 그런 다음 server.respond() 전화를 모두 제거하면 설정해야합니다!

+0

오, 멋지다. 공유 해 주셔서 감사합니다. – filur

+0

흠, 방금 테스트했는데 작동하지 않는 것 같습니다. 내가 놓친 게 무엇입니까? http://jsfiddle.net/3qj20r5m/3/ – filur

+0

아, jQuery-ism처럼 콜백에 0ms'setTimeout'을 추가 한 것 같습니다. 다음은 raw xhr을 사용하는 중첩 된 케이스입니다 : http://jsfiddle.net/3qj20r5m/5/. jQuery를 사용하면 테스트를 비동기 적으로 수행 할 수 없을 수도 있습니다./ –