Meskipun ada pertanyaan yang sama di sini tetapi saya tidak dapat menemukan jawaban untuk masalah saya, jadi inilah pertanyaan saya:
Saya menguji aplikasi node js saya menggunakan mocha dan chai. Saya menggunakan sinion untuk membungkus fungsi saya.
describe('App Functions', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('get results',function(done) {
testApp.someFun
});
}
describe('App Errors', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('throws errors',function(done) {
testApp.someFun
});
}
Ketika saya mencoba menjalankan tes ini, saya mendapat kesalahan
Attempted to wrap getObj which is already wrapped
Saya juga mencoba menempatkan
beforeEach(function () {
sandbox = sinon.sandbox.create();
});
afterEach(function () {
sandbox.restore();
});
di setiap menjelaskan, tapi tetap memberi saya kesalahan yang sama.
Jawaban:
Anda harus mengembalikan fungsi
getObj
inafter()
, silakan coba seperti di bawah ini.describe('App Functions', function(){ var mockObj; before(function () { mockObj = sinon.stub(testApp, 'getObj', () => { console.log('this is sinon test 1111'); }); }); after(function () { testApp.getObj.restore(); // Unwraps the spy }); it('get results',function(done) { testApp.getObj(); }); }); describe('App Errors', function(){ var mockObj; before(function () { mockObj = sinon.stub(testApp, 'getObj', () => { console.log('this is sinon test 1111'); }); }); after( function () { testApp.getObj.restore(); // Unwraps the spy }); it('throws errors',function(done) { testApp.getObj(); }); });
sumber
sinon.restoreAll();
yang dapat dijalankan setelah semua tes hanya untuk memastikan Anda tidak lupa untuk memulihkan sebuah rintisan.Kesalahan ini karena tidak memulihkan fungsi rintisan dengan benar. Gunakan kotak pasir lalu buat rintisan menggunakan kotak pasir. Setelah setiap pengujian di dalam suite, pulihkan sandbox
beforeEach(() => { sandbox = sinon.createSandbox(); mockObj = sandbox.stub(testApp, 'getObj', fake_function) }); afterEach(() => { sandbox.restore(); });
sumber
Untuk kasus di mana Anda perlu memulihkan semua metode dari satu objek, Anda dapat menggunakan
sinon.restore(obj)
.Contoh:
before(() => { userRepositoryMock = sinon.stub(userRepository); }); after(() => { sinon.restore(userRepository); });
sumber
// Previously sinon.restore(stubObject); // Typescript (stubObject as any).restore(); // Javascript stubObject.restore();
Saya juga memukul ini menggunakan hook sebelum () dan sesudah () dari Mocha. Saya juga menggunakan pemulihan () seperti yang disebutkan di mana-mana. File pengujian tunggal berjalan dengan baik, beberapa tidak. Akhirnya ditemukan tentang Mocha root-level-hooks : Saya tidak memiliki sebelum () dan sesudah () di dalam saya sendiri menjelaskan (). Jadi, ia menemukan semua file dengan before () di tingkat root dan mengeksekusinya sebelum memulai pengujian apa pun.
Jadi, pastikan Anda memiliki pola yang serupa:
describe('my own describe', () => { before(() => { // setup stub code here sinon.stub(myObj, 'myFunc').callsFake(() => { return 'bla'; }); }); after(() => { myObj.myFunc.restore(); }); it('Do some testing now', () => { expect(myObj.myFunc()).to.be.equal('bla'); }); });
sumber
Disarankan untuk menginisialisasi stub di 'beforeEach' dan memulihkannya di 'afterEach'. Tetapi jika Anda ingin bertualang, berikut ini juga berfungsi.
describe('App Functions', function(){ let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => { //some stuff }); it('get results',function(done) { testApp.someFun mockObj .restore(); }); } describe('App Errors', function(){ let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => { //some stuff }); it('throws errors',function(done) { testApp.someFun mockObj .restore(); }); }
sumber
Bahkan dengan kotak pasir itu bisa memberi Anda kesalahan. Terutama saat pengujian dijalankan secara paralel untuk kelas ES6.
const sb = sandbox.create(); before(() => { sb.stub(MyObj.prototype, 'myFunc').callsFake(() => { return 'whatever'; }); }); after(() => { sb.restore(); });
ini bisa menimbulkan kesalahan yang sama jika tes lain mencoba menghentikan myFunc dari Prototipe. Saya bisa memperbaikinya tetapi saya tidak bangga karenanya ...
const sb = sandbox.create(); before(() => { MyObj.prototype.myFunc = sb.stub().callsFake(() => { return 'whatever'; }); }); after(() => { sb.restore(); });
sumber
Bagi siapa pun yang mengalami masalah ini, jika Anda menghentikan atau memata-matai seluruh objek, dan kemudian Anda melakukannya
Anda masih akan mendapatkan error tersebut. Anda harus menghentikan / memata-matai metode individu.
Aku menyia-nyiakan selamanya untuk mencari tahu apa yang salah.
sinon-7.5.0
sumber
Saya mengalami ini dengan mata-mata. Perilaku ini membuat sinon sangat tidak fleksibel untuk diajak bekerja sama. Saya membuat fungsi pembantu yang mencoba menghapus mata-mata yang ada sebelum membuat yang baru. Dengan begitu saya tidak perlu khawatir tentang keadaan sebelum / sesudah. Pendekatan serupa mungkin juga berhasil untuk stub.
import sinon, { SinonSpy } from 'sinon'; /** * When you set a spy on a method that already had one set in a previous test, * sinon throws an "Attempted to wrap [function] which is already wrapped" error * rather than replacing the existing spy. This helper function does exactly that. * * @param {object} obj * @param {string} method */ export const spy = function spy<T>(obj: T, method: keyof T): SinonSpy { // try to remove any existing spy in case it exists try { // @ts-ignore obj[method].restore(); } catch (e) { // noop } return sinon.spy(obj, method); };
sumber
function stub(obj, method) { // try to remove any existing stub in case it exists try { obj[method].restore(); } catch (e) { // eat it. } return sinon.stub(obj, method); }
dan gunakan fungsi ini saat membuat stub dalam pengujian. Ini akan menyelesaikan kesalahan 'Kesalahan Sinon Mencoba membungkus fungsi yang sudah dibungkus'.
contoh:
stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
sumber