2017-04-25 116 views
3

單元測試期間,我遇到了打字稿的問題。我試圖單元測試的模塊,如下面的代碼示例:使用依賴注入進行單元測試

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

爲了測試提出我想知道,如果快遞()得到()被調用,如果第一個參數是「/測試」。在我切換到typescript之前,我總是使用模塊sinonJS來窺探或存根功能,以便我可以正確使用某個依賴項的測試。現在使用Typescript,我遇到了我在模塊中設置的嚴格類型的問題。舉例:

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

上述結果在下面的打字稿編譯錯誤的代碼示例:

error TS2339: Property 'called' does not exist on type 'ApplicationRequestHandler<Express>'. 

我明白爲什麼打字稿回報這個錯誤,不知何故,甚至是明顯的。我甚至知道一個可能的解決方案,我接受模塊中的任何Express。

但我正在尋找一種更優雅的方式能夠間諜/存根/模擬我的依賴測試建議,但同時具有嚴格打字的優點。

+0

另外,在單元測試你爲什麼_create_整個快遞應用程序? – atoth

回答

1

如您所述,您指定Express作爲BootClassInterface接口上的返回類型。因此app將被視爲Express,它會查找它的屬性而不是你的模擬。

您也可以只投一個app的房產any。嘗試:

chai.assert.equal((<any>app.get).called, 1) 

或者使用興農類型定義:

chai.assert.equal((<SinonSpy>app.get).called, 1)