Beschreiben Sie den Fehler
Wenn ich sinon.createStubInstance(X)
, wobei X eine Klasse mit mindestens einem privaten Mitglied ist, erhalte ich Fehler wie:
Argument vom Typ „SinonStubbedInstance
' ist Parametern vom Typ 'Foo' nicht zuweisbar.
Die Eigenschaft „_private“ fehlt im Typ „SinonStubbedInstance', aber im Typ 'Foo' erforderlich.
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);
});
});
Reproduzieren
Schritte zum Reproduzieren des Verhaltens:
printSpeech(mockFoo)
Erwartetes Verhalten
Ich würde erwarten, dass dies ohne Fehler funktioniert. Ich interessiere mich nicht für _private(), noch beabsichtige ich, sein Verhalten direkt zu testen, aber es sollte nicht zu einem Build-Time-Fehler führen. Jasmine unterstützt diesen Fall mit jasmine.createSpyObj
, obwohl die Implementierung von Jasmine andere Mängel aufweist.
Kontext (bitte ergänzen Sie die folgenden Informationen):
Umgebung: WSL Ubuntu 16.04, Knoten 10
Andere Bibliotheken, die Sie verwenden: Mocha 5.2.0
Bearbeiten: Hier ist ein Stackblitz https://stackblitz.com/edit/typescript-nfbgno?file=index.ts
Es beschwert sich über process.stdout, weil es im Browser läuft, aber das ist unwichtig, da das eigentliche Problem die Kompilierzeit ist
Dies ist ein Typescript-Problem. Wir werden keine Zeit damit verbringen, uns damit zu befassen, da wir Typescript nicht explizit unterstützen. Dass Typescript private Member irgendwie unterstützt, ist eine Eigenschaft seines Typsystems und könnte auf verschiedene Arten implementiert werden. Als ich Typescript verwendete, löste ich solche Probleme oft, indem ich zum Typescript Playground ging und die Ausgabe untersuchte, um zu verstehen, was es tat. Das müssen Sie auch tun.
Dies ist keine endgültige Lösung, aber ich habe es geschafft, dieses Problem mit der folgenden Funktion zu beheben:
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>;
}
Offensichtlich implementiert dies keine privaten Methoden, und als solche können Sie sie nicht aufrufen (und sollten dies auch nicht). Durch die Verwendung dieser Wrapper-Funktion erhalten Sie eine Codevervollständigung für alle öffentlichen Funktionen/Member in Ihrer Klasse sowie für die Stub-Hilfsfunktionen von sinon und StubbedClass
Ist die Antwort von @pauloavelar immer noch die empfohlene Problemumgehung?
Hilfreichster Kommentar
Dies ist keine endgültige Lösung, aber ich habe es geschafft, dieses Problem mit der folgenden Funktion zu beheben:
Offensichtlich implementiert dies keine privaten Methoden, und als solche können Sie sie nicht aufrufen (und sollten dies auch nicht). Durch die Verwendung dieser Wrapper-Funktion erhalten Sie eine Codevervollständigung für alle öffentlichen Funktionen/Member in Ihrer Klasse sowie für die Stub-Hilfsfunktionen von sinon und StubbedClassist ein gültiger Typ, der in Ihren Tests als T verwendet werden kann.