2017-02-27 133 views
3

假設我有一個由控制器處理的Express路由。控制器使用服務,服務使用存儲庫與數據源進行通信。Typescript/Node.js - 如何模擬集成測試的傳遞依賴關係?

我想用Supertest來測試路線創建一個集成測試:

test -> my Express app -> controller -> service -> repository -> data source 

我的問題是,我需要模擬庫/數據源,運行測試!我想對某些值進行硬編碼,就好像它們來自真實的數據源。我有什麼選擇?

在Java世界中,我將使用Spring或Guice的依賴注入,我會用這種方式替換模擬版本的存儲庫。在Typescript/Node.js世界中實現這種模擬的模式是什麼?

我想使用純Javascript,我可以使用Proxyquire及其Globally override require功能,從測試本身模擬存儲庫。但我不確定這與Stylist的效果很好。

那麼使用Typescript和Node.js從測試文件中嘲諷「深層」組件(一種傳遞性依賴)的建議方法是什麼?

+0

,還有通過護照稱爲[電解質](HTTPS的創造者一個漂亮的圖書館:// github.com/jaredhanson/electrolyte),它執行依賴注入/ IoC。你設置了文件夾,使用它的'IoC.use(..)'函數以相反的順序查找,所以在我的測試引導文件中,我添加了我的mocks文件夾,以便它首先查找,然後解析我的模擬數據源而不是其他文件夾或節點模塊中的數據源。 –

回答

4

模塊在第一次加載後被緩存,因此您可以先將它們加載到測試文件中,然後使用像sinon這樣的庫對它們進行存根。

考慮下面的代碼:

// dependency.ts 
export function foo(){ 
    return 'foo'; 
} 

// app.ts 
import {foo} from './dependency'; 
export default function main(){ 
    return 'winner ' + foo(); 
} 

您可以測試app.ts磕碰與興農依賴於以下方式:

import * as Dependency from '../src/dependency'; 
import main from '../src/app'; 

describe('test dependency',() => { 
    var fooStub; 
    beforeEach(() => { 
     fooStub = sinon.stub(Dependency, 'foo'); 
     fooStub.returns('la la lang'); 
    }); 
    afterEach(()=>{ 
     fooStub.restore(); 
    }) 

    it('uses stubbed dependency',()=>{ 
     expect(main()).to.be.equal('winner la la lang'); 
    }); 

    it('can return different values on other tests',()=>{ 
     fooStub.returns('moonlight'); 
     expect(main()).to.be.equal('winner moonlight'); 
    }); 
}); 

所以基本上你的集成測試,你可以導入和存根您啓動應用程序之前的依賴關係。我這樣做創建一個app.proxy.ts文件:

  • app.proxy導入您的資料庫和存根它返回預定義的數據。設置存根後,導入真實的app.ts並導出它。
  • 在您的集成測試文件中,導入app.proxy而不是應用程序並將其與超類一起使用。這將最終給你的應用程序,但設置了樁的依賴!
  • 編寫和運行測試,知道它如果你使用普通的節點,而不是將打字稿使用預定義的數據
相關問題