Cara memiliki nilai pengembalian yang berbeda untuk beberapa panggilan pada mata-mata Jasmine

101

Katakanlah saya memata-matai metode seperti ini:

spyOn(util, "foo").andReturn(true);

Fungsi yang diuji memanggil util.foobeberapa kali.

Mungkinkah mata-mata itu kembali truepertama kali dipanggil, tetapi kembali falseuntuk kedua kalinya? Atau apakah ada cara lain untuk melakukannya?

mikhail
sumber

Jawaban:

164

Anda dapat menggunakan spy.and.returnValues (seperti Jasmine 2.4).

sebagai contoh

describe("A spy, when configured to fake a series of return values", function() {
  beforeEach(function() {
    spyOn(util, "foo").and.returnValues(true, false);
  });

  it("when called multiple times returns the requested values in order", function() {
    expect(util.foo()).toBeTruthy();
    expect(util.foo()).toBeFalsy();
    expect(util.foo()).toBeUndefined();
  });
});

Ada beberapa hal yang harus Anda perhatikan, ada fungsi lain yang mirip dengan spell returnValuetanpa s, jika Anda menggunakan itu, Jasmine tidak akan memperingatkan Anda.

Lautan
sumber
21
+1: ini adalah fitur yang luar biasa. Sebuah kata peringatan, meskipun - berhati-hatilah untuk tidak melupakan 's' in .returnValues- kedua fungsi tersebut jelas berbeda, tetapi meneruskan beberapa argumen untuk .returnValuetidak menimbulkan kesalahan. Saya tidak ingin mengakui berapa banyak waktu yang saya buang karena satu karakter itu.
DIMM Reaper
@TheDIMMReaper, Terima kasih. Saya menyebutkannya sekarang.
Laut
Melakukannya di beforeEach penting bagi saya, bukan dalam ujian (itu)
Ian
Tidak perlu khawatir tentang kesalahan ejaan saat menggunakan jasmine di TypeScript, tentunya.
Simpanse Suka Berperang
27

Untuk versi Jasmine yang lebih lama, Anda dapat menggunakan spy.andCallFakeuntuk Jasmine 1.3 atau spy.and.callFakeuntuk Jasmine 2.0, dan Anda harus melacak status 'dipanggil', baik melalui penutupan sederhana, atau properti objek, dll.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});
voithos
sumber
4
Kita dapat memperluas ini untuk lebih dari 2 panggilan seperti: var results = [true, false, "foo"]; var callCount = 0; spyOn (util, "foo"). and.callFake (function () {return results [callCount ++];});
Jack
1
Ini bisa diperluas menjadi fungsi generik seperti: function returnValues ​​() {var args = arguments; var callCount = 0; return function () {return args [callCount ++]; }; }
Tomas Lieberkind
Mengapa seluruh kode ini ketika Anda bisa mengembalikan results.shift ()?
ThaFog
bagaimana jika kita mengembalikan observabvles
Lijo
opsi ini lebih fleksibel, karena kita bisa melempar kesalahan atau mengembalikan nilai tergantung pada urutan panggilan.
0bj3ct