Décrivez le bogue
si je sinon.createStubInstance(X)
où X est une classe avec au moins un membre privé, je reçois des erreurs comme :
Argument de type 'SinonStubbedInstance
' n'est pas assignable au paramètre de type 'Foo'.
La propriété '_private' est manquante dans le type 'SinonStubbedInstance' mais obligatoire dans le type '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);
});
});
Reproduire
Étapes pour reproduire le comportement :
printSpeech(mockFoo)
Comportement attendu
Je m'attendrais à ce que cela fonctionne sans erreur. Je ne me soucie pas de _private(), et je n'ai pas non plus l'intention de tester directement son comportement, mais cela ne devrait pas entraîner d'erreur de construction. Jasmine prend en charge ce cas avec jasmine.createSpyObj
, bien que l'implémentation de jasmine ait d'autres défauts.
Contexte (veuillez compléter les informations suivantes) :
Environnement : WSL Ubuntu 16.04, nœud 10
Autres bibliothèques que vous utilisez : Mocha 5.2.0
edit : voici un stackblitz https://stackblitz.com/edit/typescript-nfbgno?file=index.ts
Il se plaint de process.stdout car il s'exécute dans le navigateur, mais ce n'est pas important car le problème réel est au moment de la compilation
Il s'agit d'un problème de dactylographie. Nous n'allons pas perdre de temps à examiner cela, car nous ne prenons pas explicitement en charge Typescript. Que Typescript ait en quelque sorte un support pour les membres privés est une propriété de son système de type et pourrait être implémenté de plusieurs façons. Lorsque j'utilisais Typescript, je résolvais souvent ces problèmes en allant sur le terrain de jeu Typescript et en inspectant la sortie pour comprendre ce qu'elle faisait. C'est ce que vous devez faire aussi.
Ce n'est pas une solution définitive, mais j'ai réussi à résoudre ce problème avec la fonction suivante :
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>;
}
Évidemment, cela n'implémente aucune méthode privée, et en tant que tel, vous ne pouvez pas (et ne devriez pas par conception) les appeler. En utilisant cette fonction wrapper, vous obtenez la complétion de code pour toutes les fonctions/membres publics de votre classe ainsi que les fonctions d'assistance de stub de sinon et StubbedClass
La réponse @pauloavelar est-elle toujours la solution de contournement recommandée ?
Commentaire le plus utile
Ce n'est pas une solution définitive, mais j'ai réussi à résoudre ce problème avec la fonction suivante :
Évidemment, cela n'implémente aucune méthode privée, et en tant que tel, vous ne pouvez pas (et ne devriez pas par conception) les appeler. En utilisant cette fonction wrapper, vous obtenez la complétion de code pour toutes les fonctions/membres publics de votre classe ainsi que les fonctions d'assistance de stub de sinon et StubbedClassest un type valide à utiliser comme T dans vos tests.