看起来通常在typescript中导入的方法会阻止模块被模拟......假设我在一个用printcript编写的node.js项目中有以下产品代码,我想测试它:
// host.ts
import http = require('http');
export class Host {
public start(port: number): http.Server {
return http.createServer().listen(port);
}
}
我使用mockery(d.ts in pull request #3313)和mocha:
进行下面的单元测试import chai = require('chai');
import mockery = require('mockery');
import webserver = require('../hosting/host');
describe('host', (): void => {
describe('start()', (): void => {
before(() : void => {
mockery.enable();
});
after((): void => {
mockery.deregisterAll();
mockery.disable();
});
it('should create an http server', (): void => {
mockery.registerMock('http', {
Server: mocks.Server,
createServer: (app: any) : any => new mocks.Server(app)
});
var host: webserver.Host = new webserver.Host({ port: 111 });
var server: any = host.start();
chai.expect(server).is.instanceOf(mocks.Server);
});
});
});
module mocks {
'use strict';
export class Server {
app: any;
constructor(app: any) {
this.app = app;
}
}
}
问题是,当调用import webserver = require('../hosting/host')
时,测试中的模拟还没有设置,并且返回了未模拟的require('http')
。我试图在var http = require('http')
函数中尝试Host.start
,但这会阻止http.Server被声明为返回值。
我应该如何使用Mocks在Typescript中实现单元测试?是否有更好的图书馆而不是嘲弄哪个更好?
答案 0 :(得分:6)
在网上搜索了一整天之后,我终于明白了:是的,在使用Typescript进行摩卡测试时使用Mockery有一个技巧。诀窍是使用typeof
标识符来引用模块。我在the Optional Module Loading and Other Advanced Loading Scenarios in this document中发现了这一点。
我的更新代码现在看起来像这样:
// host.ts
import httpDef = require('http');
export class Host {
public start(port: number): httpDef .Server {
var http: typeof httpDef = require('http');
return http.createServer().listen(port);
}
}
这允许我在我的摩卡测试中设置模拟,如下所示:
import chai = require('chai');
import mockery = require('mockery');
import webserver = require('../hosting/host');
import httpDef = require('http'):
describe('host', (): void => {
describe('start()', (): void => {
before(() : void => {
mockery.enable();
});
after((): void => {
mockery.deregisterAll();
mockery.disable();
});
it('should create an http server', (): void => {
var mockServer: httpDef.Server = <httpDef.Server>{};
var mockHttp: typeof httpDef = <typeof httpDef>{};
mockHttp.createServer = () : httpDef.Server => mockServer;
mockery.registerMock('http', mockHttp);
var host: webserver.Host = new webserver.Host({ port: 111 });
var server: any = host.start();
chai.expect(server).is.equals(mockServer);
});
});
});
可以在here找到可以用于依赖注入的其他一些场景。