假设我有一条由控制器处理的Express路线。控制器使用服务,服务使用存储库与数据源通信。
我想使用Supertest创建一个集成测试来测试该路由:
test -> my Express app -> controller -> service -> repository -> data source
我的问题是我需要模拟存储库/数据源,才能运行测试!我想硬编码一些值,好像它们来自真实的数据源。我有什么选择?
在Java世界中,我将使用Spring或Guice的依赖注入,我会用这样的模拟版本替换存储库。在Typescript / Node.js世界中实现这种模拟的模式是什么?
我想使用普通的Javascript我可以使用Proxyquire
及其Globally override require功能,从测试本身模拟存储库。但我不确定这是否适用于Typescript。
那么使用Typescript和Node.js从测试文件中模拟“深层”组件(传递依赖)的推荐方法是什么?
答案 0 :(得分:7)
模块在第一次加载后被缓存,因此您可以先在测试文件中加载它们,然后使用像sinon这样的库来存储它们。
请考虑以下代码:
dcast(df_last, id ~ last_date, length, drop = FALSE, value.var = "last_date")
# Top Corner
id 1979-12-29 1980-06-29 1980-12-28 1981-06-29 1981-12-28 1982-06-29 1982-12-28
1: 1 0 0 0 0 0 0 0
2: 2 0 0 0 0 0 0 0
3: 3 0 0 0 0 0 0 0
4: 4 0 0 0 0 1 0 0
5: 5 0 1 0 0 0 0 0
6: 6 0 0 0 0 0 0 0
7: 7 0 0 0 0 0 0 0
8: 8 0 0 0 0 0 0 0
您可以通过以下方式测试app.ts使用sinon对其依赖性进行测试:
// dependency.ts
export function foo(){
return 'foo';
}
// app.ts
import {foo} from './dependency';
export default function main(){
return 'winner ' + foo();
}
因此,基本上对于集成测试,您可以在启动应用程序之前导入和存根依赖项。我这样做了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,并将其与supertest一起使用。这将最终为您提供应用程序,但是在设置了存根依赖项之后!