Tengo problemas con mecanografiado durante las pruebas unitarias. Intento realizar una prueba unitaria de un módulo como el siguiente código de ejemplo:
import {Express} from 'express' export interface BootClassInterface { setup(): Express } export class BootClass implements BootClassInterface { constructor(private express: () => Express ){ } public test(){ const app = this.express() app.get("/test", (req, res) => { res.send("Hello World") }) return app; } }Para la propuesta de prueba, quiero saber si se llamó a express().get() y si el primer parámetro fue '/ test'. Antes de cambiar a mecanografiado, siempre usaba el módulo sinonJS para espiar o bloquear la funcionalidad para poder probar que cierta dependencia se usaba correctamente. Ahora con Typescript me encuentro con problemas con los tipos estrictos que configuré en el módulo. Por ejemplo:
import * as chai from 'chai' import 'mocha' import * as sinon from 'sinon' import * as express from 'express' import * as Boot from '../../src/Core/Boot' const assert = chai.assert suite('[CORE] unit test /Core/Boot.ts', () => { let BootClass: Boot.BootClassInterface setup(() => { const expressApp = () => { const app = express() app.get = sinon.spy() return app } const Services: Boot.BootServicesInterface = { express: expressApp } BootClass = new Boot.BootClass(Services) }) test('Do first test', () => { const app = BootClass.setup() chai.assert.equal(app.get.called, 1) }) })El ejemplo de código anterior da como resultado el siguiente error de compilación de TypeScript:
error TS2339: Property 'called' does not exist on type 'ApplicationRequestHandler<Express>'.Puedo ver por qué mecanografiado devuelve este error y de alguna manera es incluso obvio. Incluso conozco una posible solución en la que acepto Express como cualquiera en el módulo.
Pero estoy buscando una forma más elegante de poder espiar/aplicar/simular mis dependencias para la propuesta de prueba, pero al mismo tiempo tener las ventajas de una tipificación estricta.
Como ha indicado, especifica Express como el tipo de devolución en la interfaz BootClassInterface . Por lo tanto, la app se consideraría Express y buscará sus propiedades en lugar de su simulacro.
También puede lanzar una propiedad de la app como any . Tratar:
chai.assert.equal((<any>app.get).called, 1)O usando la definición de tipo Sinon:
chai.assert.equal((<SinonSpy>app.get).called, 1)