Jelaskan bugnya
jika saya sinon.createStubInstance(X)
di mana X adalah kelas dengan setidaknya satu anggota pribadi, saya menerima kesalahan seperti:
Argumen bertipe 'SinonStubbedInstance
' tidak dapat ditetapkan ke parameter tipe 'Foo'.
Properti '_private' tidak ada dalam jenis 'SinonStubbedInstance' tetapi diperlukan dalam jenis 'Foo'.
describe('SinonTest', () => {
class Foo {
public talk() {
return 'hi';
}
private _private() {
return null;
}
}
function printSpeech(foo: Foo) {
console.log(foo.talk());
}
it('should allow you to pass a stub as a the original', () => {
const mockFoo = sinon.createStubInstance(Foo);
printSpeech(mockFoo);
});
});
Untuk Mereproduksi
Langkah-langkah untuk mereproduksi perilaku:
printSpeech(mockFoo)
Perilaku yang diharapkan
Saya berharap ini berfungsi tanpa kesalahan. Saya tidak peduli dengan _private(), saya juga tidak bermaksud menguji perilakunya secara langsung, tetapi seharusnya tidak menghasilkan kesalahan waktu pembuatan. Jasmine mendukung kasus ini dengan jasmine.createSpyObj
, meskipun implementasi melati memiliki kekurangan lain.
Konteks (harap lengkapi informasi berikut):
Lingkungan: WSL Ubuntu 16.04, Node 10
Pustaka lain yang Anda gunakan: Mocha 5.2.0
edit: inilah stackblitz https://stackblitz.com/edit/typescript-nfbgno?file=index.ts
Itu mengeluh tentang process.stdout karena berjalan di browser, tapi itu tidak penting karena masalah sebenarnya adalah waktu kompilasi
Ini adalah masalah TypeScript. Kami tidak akan menggunakan waktu untuk menyelidiki ini, karena kami tidak mendukung TypeScript secara eksplisit. TypeScript itu entah bagaimana memiliki dukungan untuk anggota pribadi adalah properti dari sistem tipenya dan dapat diimplementasikan dalam beberapa cara. Ketika saya menggunakan TypeScript, saya sering menyelesaikan masalah seperti itu dengan pergi ke taman bermain TypeScript dan memeriksa hasilnya untuk memahami apa yang dilakukannya. Itulah yang perlu Anda lakukan juga.
Ini bukan solusi yang pasti, tetapi saya berhasil memperbaiki masalah ini dengan fungsi berikut:
import { createStubInstance, StubbableType, SinonStubbedInstance, SinonStubbedMember } from 'sinon';
export type StubbedClass<T> = SinonStubbedInstance<T> & T;
export function createSinonStubInstance<T>(
constructor: StubbableType<T>,
overrides?: { [K in keyof T]?: SinonStubbedMember<T[K]> },
): StubbedClass<T> {
const stub = createStubInstance<T>(constructor, overrides);
return stub as unknown as StubbedClass<T>;
}
Jelas, ini tidak menerapkan metode pribadi apa pun, dan karena itu Anda tidak dapat (dan tidak boleh dengan desain) memanggilnya. Dengan menggunakan fungsi pembungkus ini, Anda mendapatkan penyelesaian kode untuk semua fungsi/anggota publik di kelas Anda serta fungsi pembantu rintisan sinon, dan StubbedClass
Apakah jawaban @pauloavelar masih merupakan solusi yang disarankan?
Komentar yang paling membantu
Ini bukan solusi yang pasti, tetapi saya berhasil memperbaiki masalah ini dengan fungsi berikut:
Jelas, ini tidak menerapkan metode pribadi apa pun, dan karena itu Anda tidak dapat (dan tidak boleh dengan desain) memanggilnya. Dengan menggunakan fungsi pembungkus ini, Anda mendapatkan penyelesaian kode untuk semua fungsi/anggota publik di kelas Anda serta fungsi pembantu rintisan sinon, dan StubbedClassadalah tipe yang valid untuk digunakan sebagai T dalam pengujian Anda.