Sinon: No se puede crear StubInstance en la clase con miembros privados

Creado en 4 ene. 2019  ·  3Comentarios  ·  Fuente: sinonjs/sinon

Describa el error
si hago sinon.createStubInstance(X) donde X es una clase con al menos un miembro privado, recibo errores como:

Argumento de tipo 'SinonStubbedInstance' no es asignable a un parámetro de tipo 'Foo'.
Falta la propiedad '_private' en el tipo 'SinonStubbedInstance' pero requerido en el tipo '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);
  });
});

Reproducir
Pasos para reproducir el comportamiento:

  1. Configure un proyecto con moka y sinon.
  2. Crear un archivo de especificaciones de prueba de unidad
  3. Pegue el fragmento de código anterior y agregue las importaciones requeridas
  4. Ver error en línea con printSpeech(mockFoo)

Comportamiento esperado
Espero que esto funcione sin errores. No me importa _private(), ni tengo la intención de probar directamente su comportamiento, pero no debería generar un error de tiempo de compilación. Jasmine admite este caso con jasmine.createSpyObj , aunque la implementación de jasmine tiene otros defectos.

Contexto (por favor complete la siguiente información):

  • Versión de la biblioteca: sinon: 7.2.2, @types/sinon: 7.0.3
  • Entorno: WSL Ubuntu 16.04, Nodo 10

  • Otras bibliotecas que está utilizando: Mocha 5.2.0

editar: aquí hay un stackblitz https://stackblitz.com/edit/typescript-nfbgno?file=index.ts

Se queja de process.stdout porque se está ejecutando en el navegador, pero eso no es importante ya que el problema real es el tiempo de compilación.

Comentario más útil

Esta no es una solución definitiva, pero logré solucionar este problema con la siguiente función:

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>;
}

Obviamente, esto no implementa ningún método privado y, como tal, no puede (y no debe por diseño) llamarlos. Al usar esta función contenedora, obtiene la finalización del código para todas las funciones/miembros públicos de su clase, así como para las funciones auxiliares de stub de sinon y StubbedClasses un tipo válido para ser utilizado como T en sus pruebas.

Todos 3 comentarios

Este es un problema de mecanografiado. No vamos a usar el tiempo investigando esto, ya que no admitimos Typescript explícitamente. Que Typescript de alguna manera tenga soporte para miembros privados es una propiedad de su sistema de tipos y podría implementarse de varias maneras. Cuando usaba Typescript, a menudo resolvía estos problemas yendo al área de juegos de Typescript e inspeccionando la salida para comprender lo que hacía. Eso es lo que tienes que hacer también.

Esta no es una solución definitiva, pero logré solucionar este problema con la siguiente función:

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>;
}

Obviamente, esto no implementa ningún método privado y, como tal, no puede (y no debe por diseño) llamarlos. Al usar esta función contenedora, obtiene la finalización del código para todas las funciones/miembros públicos de su clase, así como para las funciones auxiliares de stub de sinon y StubbedClasses un tipo válido para ser utilizado como T en sus pruebas.

¿La respuesta de @pauloavelar sigue siendo la solución alternativa recomendada?

¿Fue útil esta página
0 / 5 - 0 calificaciones