否则 server.autoRespond

sinon server.autoRespond

我正在学习测试,所以我使用 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 fake-server 不会立即响应请求,但会有短暂的延迟。所以我必须使用 done() Funktion 异步进行茉莉花测试。 所以下面的代码有效:

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),但如果你更新到最新版本,你应该能够得到它。 Check out the docs here.

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