sinon server.autoRespond

sinon server.autoRespond

本文关键字:autoRespond server sinon      更新时间:2024-04-19

我正在学习测试,所以我使用karma、karma jasmine和sinon.js构建了这个简单的例子:我有一个ajax请求,一旦成功,它就会设置一个全局变量。使用sinon fakeServer,我伪造响应,如果我手动使用sinon.server.respond()函数触发响应,一切都会好起来。但是,将sinon fakeServer更改为autoRespond=true,并不像预期的那样。测试失败,因为全局变量仍然未定义。在我看来,当设置为autoRespond=true时,fakeRequest似乎不会应答。有人建议为什么吗?谢谢你的帮助。测试代码:

var requestResult;  // global variable

function loadFirstData () {
  var request = $.ajax( {
                          url     : "/rest/first/",
                          type    : "GET",
                          timeout : 5000,
                          dataType: "json"
                      } );
  request.done( function ( data ) {
      requestResult = data;
  } );
  request.fail( function ( jqXHR, textStatus ) {
      console.error( "Request failed: " + textStatus );
      console.error( "Object: ", jqXHR );
  } );
}

测试:

describe( 'Ajax requests', function () {
  var xhr;
  beforeEach(function() {
    xhr = sinon.fakeServer.create();
    // this doesn't work
    //xhr.autoRespond = true;
    xhr.respondWith(
        'GET',
        '/rest/first/',
        function (request) {
            request.respond(
                200,
                { "Content-Type": "application/json" },
                '{ "returnValue": 20.13 }'
            );
        }
    );
    xhr.respondWith(
        'GET',
        'rest/second/',
        function (request) {
            request.respond(
                200,
                { "Content-Type": "application/json" },
                '{ "returnValue": 3333 }'
            );
        }
    );

  });
  afterEach(function() {
    xhr.restore();
  });
  it( 'should get first data', function () {
    loadFirstData();
    // this works
    xhr.respond();
    expect( requestResult ).toEqual( { "returnValue": 20.13 } );

  } );
} );

我自己找到了答案。:)sinon假冒服务器不会立即响应请求,但会有很短的延迟。因此,我必须使用done()Funktion异步进行jasmine测试。因此以下代码有效:

describe( 'Ajax requests', function () {
  var xhr;
  // beforeEach get the jasmine done as argument
  beforeEach(function(done) {
    xhr = sinon.fakeServer.create();
    // autoRespond is set
    xhr.autoRespond = true;
    xhr.respondWith(
      'GET',
      '/rest/first/',
      function (request) {
        request.respond(
            200,
            { "Content-Type": "application/json" },
            '{ "returnValue": 20.13 }'
        );
      }
    );
    xhr.respondWith(
      'GET',
      'rest/second/',
      function (request) {
        request.respond(
            200,
            { "Content-Type": "application/json" },
            '{ "returnValue": 3333 }'
        );
      }
    );
    // starts the tests
    done();
  });
  afterEach(function() {
    xhr.restore();
  });
  // the asynchronous test get the jasmie done as argument, as well
  it( 'should get first data', function (done) {
    loadFirstData();
    // delays the expectations check
    setTimeout( function() {
      expect( requestResult ).toEqual( { "returnValue": 20.13 } );
      // says jasmine the test is finished
      done();
    }, 500);
  } );
} );

Sinon文档指出,由于您发现的原因,autoRespond不适合测试。

我最终在fakeServer上实现了一个respondImmediately属性,它将同步响应任何请求。这在几周前(v1.14.0)刚刚合并到项目中,但如果你更新到最新版本,你应该可以得到它。查看此处的文档。

respondImmediately属性设置为true,而不是将autoRespond属性设置为true。然后,您可以移除所有异步done调用,并移除您期望的setTimeout包装器。希望这有助于整理你的测试!