Sinon: Bungkus pengambil dan penyetel ES5

Dibuat pada 3 Mar 2012  ·  23Komentar  ·  Sumber: sinonjs/sinon

var o = {
  get foobar() { return 'foobar' },
  set foobar(s) { throw 'bzzt!' },
  foo: function() { return 'foo' },
  bar: 'bar'
}; // -> { foobar: [Getter/Setter], foo: [Function], bar: 'bar' }

sinon.mock(o).expects('foobar').returns('woohoo'); // doesn't because sinon.wrapMethod() does an object[property] which accesses the getter which returns a string

Untuk mendukung getter dan setter, Anda perlu melakukan Object.getOwnPropertyDescriptor(obj, prop) untuk objek dan kemudian Object.getPrototypeOf(obj) rekursif jika tidak ada, deskriptor memiliki 'get' dan 'set' properti di mana mereka didefinisikan.

Tapi, Anda mungkin ingin mengejek pengambil atau penyetel saja atau keduanya, jadi bagaimana Anda menentukannya? Beberapa opsi:

mock(o).expects('foobar'); // ambiguous, the setter? getter? or both?
mock(o).expects('get foobar'); // ambiguous, there may be a legitimate property named "get foobar"
mock(o).expectsGet('foobar'); // clear but more code in Sinon and more to document ?
mock(o).expectsSet('foobar'); // ditto

Dan juga, apakah Anda sudah memiliki konvensi untuk menangani fitur yang mungkin tidak ada di lingkungan saat ini? Jika seseorang mencoba melakukan ini di IE6, apa yang seharusnya terjadi?

Komentar yang paling membantu

Satu kasus penggunaan yang tidak biasa adalah di mana pengambil disediakan tetapi penyetel tidak, yang membuat properti hanya-baca, yang mungkin merupakan ide bagus untuk kode produksi, tetapi menghalangi pengujian. Memiliki pengambil dan penyetel dukungan Sinon akan berbicara dengan kasus penggunaan itu.

Semua 23 komentar

Melihat contoh Anda, saya tidak sepenuhnya yakin bahwa mocking getter adalah praktik pengujian yang baik - saya akan berasumsi bahwa hanya mengatur properti ke beberapa nilai selama pengujian akan sangat membantu dalam banyak kasus (?)

Bagaimanapun, bagaimana jika rintisan adalah objek dan bukan fungsi, itu akan diperlakukan sebagai deskriptor properti? Sesuatu seperti:

stub(o, "foobar", { get: function () { return 42; } });

Saya tidak yakin bagaimana menyelesaikan harapan Anda. Tapi seperti yang saya katakan - tetapi apakah layak menempatkan harapan palsu pada pencarian properti? Menurut saya jika Anda membutuhkannya, mungkin itu harus menjadi metode "aktual"?

Contohnya adalah sederhana. Kode sebenarnya yang saya coba lakukan ini disebut get identifier yang menambahkan beberapa hal bersama-sama, beberapa di antaranya berasal dari tempat yang tidak ingin saya repotkan dalam pengujian, saya hanya ingin mengonfirmasi itu x.identifier diakses dan kemudian memiliki kendali atas apa yang dikembalikan. Untuk saat ini saya akan menggunakan getIdentifier() yang baik-baik saja tetapi mengingat bahwa kita mungkin melihat lebih banyak pengambil dan penyetel ke masa depan untuk properti yang dihitung, ini mungkin sesuatu yang bisa/harus ditangani Sinon?

Masih agak ragu-ragu tentang ini. Akan membiarkannya beristirahat sebentar dan memutuskan nanti. Jika Anda memiliki lebih banyak masukan/saran, jangan ragu untuk menuliskannya di sini.

Satu kasus penggunaan yang tidak biasa adalah di mana pengambil disediakan tetapi penyetel tidak, yang membuat properti hanya-baca, yang mungkin merupakan ide bagus untuk kode produksi, tetapi menghalangi pengujian. Memiliki pengambil dan penyetel dukungan Sinon akan berbicara dengan kasus penggunaan itu.

Untuk saat ini, saya tidak melihat nilai dalam mendukung getter dan setter di Sinon.

jelas, sudah lama sejak masalah ini dibahas, tetapi fitur ini akan sangat membantu ...

+1
Saya juga merindukannya. Ini akan sangat berguna ketika digunakan dengan komponen yang bekerja sebagai abstraksi dengan getter atas beberapa sumber daya yang mendasarinya, seperti file, atau objek database. Akan menyenangkan bisa mematikan getter itu.

Saya juga ingin melihat ini dibuka kembali. Ini akan berguna secara khusus untuk mematikan bidang objek lokasi yang dibungkus.

+1 untuk fitur itu!

:+1: Saya juga merasa perlu fitur ini.

:+1: Ini perlu dibuka kembali. Terutama dengan ES6 yang terus berkembang, ini lebih penting dari sebelumnya. Saya suka varian expectsGet .

+1 Saya sepenuh hati setuju dengan @simonzack

+1

Saya juga ingin melihat ini dibuka kembali. Ini akan berguna secara khusus untuk mematikan bidang objek lokasi yang dibungkus.

Apakah https://github.com/mroderick/wrapple menutup celah itu untuk Anda?

Saat ini saya menggunakan wrapple cukup luas, dan saya lupa mengomentari masalah ini. Itu mungkin berarti bahwa wrapple telah menutup celah seperti yang Anda katakan.

+1 baru saja menemukan sinon yang tidak mendukung ejekan pengambil

Hai @derwaldgeist , apakah Anda menggunakan versi terbaru Sinon?

Yang terbaru mendukung stubbing getter dengan sandboxes dan sinon.stub .

Yang harus Anda lakukan adalah menggunakan fungsi get , misalnya:

var myObj = {
    prop: "foo"
};

createStub(myObj, "prop").get(function getterFn() {
    return "bar";
});

myObj.prop // "bar"

Tolong beri tahu saya jika ini sesuai dengan kasus penggunaan Anda atau jika Anda memiliki keraguan lebih lanjut.

Terima kasih telah kembali secepat itu, sangat dihargai.
Namun, saya tidak menemukan bagaimana Anda dapat memulihkan pengambil yang telah ditentukan seperti itu? Saya bahkan melihat kode sumber sinon dan tidak dapat melihat mekanisme yang menyimpan pengambil asli saat memanggil get().

Hai @derwaldgeist ,

Memang mungkin untuk memulihkan getter, bahkan jika mereka tidak ditentukan sebelum dimatikan. Yang harus Anda lakukan adalah memanggil metode restore di rintisan yang dibuat, misalnya:

var myObj = {
    prop: "foo"
};

var stub = createStub(myObj, "prop");

stub.get(function getterFn() {
    return "baz";
});

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

Kami menambahkan metode restore ini baik dalam metode stub itu sendiri (saat mematikan properti non-fungsi) atau di utilitas wrapMethod .

Wow, itu cepat. Saya mencoba ini:

 const stub = sinon.stub(myObj, 'prop');
 stub.get(() => ({}));
  ...
 stub.restore();

tetapi ketika menjalankan restore() dikatakan: Cannot redefine property: prop

Dari mana metode createStub berasal?

@derwaldgeist saya mendapatkannya dari tes, maaf, lupa mengeditnya. Tapi bagaimanapun, itu sama dengan sinon.stub .

Bisakah Anda memberi tahu saya versi sinon apa yang Anda gunakan sehingga saya dapat memeriksanya?

Saya pikir mungkin Anda belum menggunakan versi terbaru di mana kami memperbaiki bug di mana Anda tidak dapat memulihkan properti karena properti didefinisikan tanpa configurable: true dan oleh karena itu kami tidak dapat mengubah deskriptornya.

Saya melihat hal yang sama dengan @derwaldgeist. Saya _think_ Saya menggunakan v4, tetapi beberapa deps lain menggunakan v1.7, jadi saya tidak yakin mana yang _sebenarnya_ digunakan. Saya tidak melihat sinon.version mana saya bisa memeriksa saat run time.

@jshado1 Jika Anda ingin tahu versi utama mana yang Anda gunakan, Anda dapat merujuk ke changelog atau panduan migrasi dan menguji perubahan yang melanggar. Untuk versi 4, Anda dapat menyatakan bahwa sinon.stub({}, 'nonExistingProperty') throws

Apakah halaman ini membantu?
0 / 5 - 0 peringkat