Jasmine文檔(三)

前言

這是我翻譯的Jasmine文檔第三篇,前兩篇文章的地址爲:
Jasmine文檔(一)
Jasmine文檔(二)

匹配全局jasmine.any

jasmine.any傳遞一個構造函數(constructor)或者“類”(class)作爲一個期望值,如果實際構造函數和傳遞的參數相同則返回true。例如:

describe("jasmine.any", function() {
  it("matches any value", function() {
    expect({}).toEqual(jasmine.any(Object));
    expect(12).toEqual(jasmine.any(Number));
  });

  describe("when used with a spy", function() {
    it("is useful for comparing arguments", function() {
      var foo = jasmine.createSpy('foo');
      foo(12, function() {
        return true;
      });

      expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function));
    });
  });
});

匹配存在jasmine.anything

jasmine.anything函數只要實際值不爲null或undefined則返回true。例如:

describe("jasmine.anything", function() {
  it("matches anything", function() {
    expect(1).toEqual(jasmine.anything());
  });

  describe("when used with a spy", function() {
    it("is useful when the argument can be ignored", function() {
      var foo = jasmine.createSpy('foo');
      foo(12, function() {
        return false;
      });

      expect(foo).toHaveBeenCalledWith(12, jasmine.anything());
    });
  });
});

局部匹配jasmine.objectContaining

jasmine.objectContaining()用於匹配那些只關心實際值中是否存在預測鍵值對的時候,若存在則返回true,例如:

describe("jasmine.objectContaining", function() {
  var foo;

  beforeEach(function() {
    foo = {
      a: 1,
      b: 2,
      bar: "baz"
    };
  });

  it("matches objects with the expect key/value pairs", function() {
    expect(foo).toEqual(jasmine.objectContaining({
      bar: "baz"
    }));
    expect(foo).not.toEqual(jasmine.objectContaining({
      c: 37
    }));
  });

  describe("when used with a spy", function() {
    it("is useful for comparing arguments", function() {
      var callback = jasmine.createSpy('callback');

      callback({
        bar: "baz"
      });

      expect(callback).toHaveBeenCalledWith(jasmine.objectContaining({
        bar: "baz"
      }));
      expect(callback).not.toHaveBeenCalledWith(jasmine.objectContaining({
        c: 37
      }));
    });
  });
});

局部數組匹配jasmine.arrayContaining

jasmine.arrayContaining()用於匹配實際數組中是否存在預測的值,存在則返回true。例如:

describe("jasmine.arrayContaining", function() {
  var foo;

  beforeEach(function() {
    foo = [1, 2, 3, 4];
  });

  it("matches arrays with some of the values", function() {
    expect(foo).toEqual(jasmine.arrayContaining([3, 1]));
    expect(foo).not.toEqual(jasmine.arrayContaining([6]));
  });

  describe("when used with a spy", function() {
    it("is useful when comparing arguments", function() {
      var callback = jasmine.createSpy('callback');

      callback([1, 2, 3, 4]);

      expect(callback).toHaveBeenCalledWith(jasmine.arrayContaining([4, 2, 3]));
      expect(callback).not.toHaveBeenCalledWith(jasmine.arrayContaining([5, 2]));
    });
  });
});

字符串匹配jasmine.stringMatching

jasmine.stringMatching()用於你不想在一個較大的對象精確匹配字符串時,或者只是匹配spy預測值的部分字符串時,匹配成功返回true。例如:

describe('jasmine.stringMatching', function() {
  it("matches as a regexp", function() {
    expect({foo: 'bar'}).toEqual({foo: jasmine.stringMatching(/^bar$/)});
    expect({foo: 'foobarbaz'}).toEqual({foo: jasmine.stringMatching('bar')});
  });

  describe("when used with a spy", function() {
    it("is useful for comparing arguments", function() {
      var callback = jasmine.createSpy('callback');

      callback('foobarbaz');

      expect(callback).toHaveBeenCalledWith(jasmine.stringMatching('bar'));
      expect(callback).not.toHaveBeenCalledWith(jasmine.stringMatching(/^bar$/));
    });
  });
});

定製不對稱的測試器

當你需要檢查符合一定標準但不必嚴格相等的一些東西時,通過調用asymmetricMatch方法可以簡單地制定一個自定義的不對稱測試器,例如:

describe("custom asymmetry", function() {
  var tester = {
    asymmetricMatch: function(actual) {
      var secondValue = actual.split(',')[1];
      return secondValue === 'bar';
    }
  };

  it("dives in deep", function() {
    expect("foo,bar,baz,quux").toEqual(tester);
  });

  describe("when used with a spy", function() {
    it("is useful for comparing arguments", function() {
      var callback = jasmine.createSpy('callback');

      callback('foo,bar,baz');

      expect(callback).toHaveBeenCalledWith(tester);
    });
  });
});

Jasmine Clock

該語法在Jasmine2.0修改。Jasmine Clock用於測試與時間有關的代碼。
在需要操作時間的spec或者Suites中調用jasmine.clock().install()來安裝。而完成之後要確保卸載來回復原來的功能。

模擬JavaScript超時函數

你可以使用setTimeout或者setInterval超時同步執行已聲明的函數。爲了執行函數,使用jasmine.clock().tick()函數來推動時間前進,該函數傳遞一個毫秒數作爲參數。

模擬日期

Jasmine Clock同樣可以用來模擬當前日期。如果不提供一個基準時間給mockDate(),它將使用當前日期。

例如:

describe("Manually ticking the Jasmine Clock", function() {
  var timerCallback;
  beforeEach(function() {
    timerCallback = jasmine.createSpy("timerCallback");
    jasmine.clock().install();
  });
  afterEach(function() {
    jasmine.clock().uninstall();
  });
  it("causes a timeout to be called synchronously", function() {
    setTimeout(function() {
      timerCallback();
    }, 100);

    expect(timerCallback).not.toHaveBeenCalled();

    jasmine.clock().tick(101);

    expect(timerCallback).toHaveBeenCalled();
  });

  it("causes an interval to be called synchronously", function() {
    setInterval(function() {
      timerCallback();
    }, 100);

    expect(timerCallback).not.toHaveBeenCalled();

    jasmine.clock().tick(101);
    expect(timerCallback.calls.count()).toEqual(1);

    jasmine.clock().tick(50);
    expect(timerCallback.calls.count()).toEqual(1);

    jasmine.clock().tick(50);
    expect(timerCallback.calls.count()).toEqual(2);
  });
  describe("Mocking the Date object", function(){
    it("mocks the Date object and sets it to a given time", function() {
      var baseTime = new Date(2013, 9, 23);
      jasmine.clock().mockDate(baseTime);

      jasmine.clock().tick(50);
      expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
    });
  });
});

異步支持

該語法在Jasmine2.0開始支持。Jasmine同樣支持執行包含異步操作。
調用beforeEachafterEachbeforeAllafterAllit時可以傳遞一個可選的單一變量,該變量在異步工作結束後可以調用。
Jasmine在判斷超時失敗前會默認等待5秒去完成異步操作。如果done還沒執行,而5秒時間到期,當前的spec會被標記爲失敗,而接下來的會繼續執行,就好像那個done已經調用了。
如果一個特定的spec需要更多時間,可以通過傳遞一個超時的值來調整。
如果所有的suite有一個不同的超時,jasmine.DEFAULT_TIMEOUT_INTERVAL可以在全局設置,在任何給定的describe之外。

describe("Asynchronous specs", function() {
  var value;
  beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
  });
  it("should support async execution of test preparation and expectations", function(done) {
//該片段在beforeEach裏的done()調用之前不會開始執行
    value++;
    expect(value).toBeGreaterThan(0);
    done();//該片段在該done()沒執行前並不會完成測試
  });

  describe("long asynchronous specs", function() {
    beforeEach(function(done) {
      done();
}, 1000);

    it("takes a long time", function(done) {
      setTimeout(function() {
        done();
      }, 9000);
    }, 10000);

    afterEach(function(done) {
      done();
    }, 1000);
  });
  describe("A spec using done.fail", function() {
    var foo = function(x, callBack1, callBack2) {
      if (x) {
        setTimeout(callBack1, 0);
      } else {
        setTimeout(callBack2, 0);
      }
    };

    it("should not call the second callBack", function(done) {
      foo(true,
        done,
        function() {
          //done.fail()可以導致spec失敗,而標誌該spec爲完成
          done.fail("Second callback has been called");
        }
      );
    });
  });
});

這是我第一次翻譯文章,有什麼不好的地方還請批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章