Sinon: StubInstance kann nicht für Klasse mit privaten Membern erstellt werden

Erstellt am 4. Jan. 2019  ·  3Kommentare  ·  Quelle: sinonjs/sinon

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:

  1. Richten Sie ein Projekt mit Mocha und Sinon ein.
  2. Erstellen Sie eine Unit-Test-Spezifikationsdatei
  3. Fügen Sie das obige Code-Snippet ein und fügen Sie alle erforderlichen Importe hinzu
  4. Siehe Fehler in Zeile mit 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):

  • Bibliotheksversion: sinon: 7.2.2, @types/sinon: 7.0.3
  • 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

Hilfreichster Kommentar

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 StubbedClassist ein gültiger Typ, der in Ihren Tests als T verwendet werden kann.

Alle 3 Kommentare

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 StubbedClassist ein gültiger Typ, der in Ihren Tests als T verwendet werden kann.

Ist die Antwort von @pauloavelar immer noch die empfohlene Problemumgehung?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

zimtsui picture zimtsui  ·  3Kommentare

stephanwlee picture stephanwlee  ·  3Kommentare

NathanHazout picture NathanHazout  ·  3Kommentare

sudhirbits picture sudhirbits  ·  4Kommentare

kevinburkeshyp picture kevinburkeshyp  ·  4Kommentare