使用 Typescript 在 Mocha 测试中使用 Mockery 有技巧吗?
Posted
技术标签:
【中文标题】使用 Typescript 在 Mocha 测试中使用 Mockery 有技巧吗?【英文标题】:Is there a trick to using Mockery in Mocha test with Typescript? 【发布时间】:2015-02-12 05:26:32 【问题描述】:在打字稿中导入的常用方法似乎可以防止模块被模拟......假设我在一个用打字稿编写的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')
。我试图在 Host.start
函数中尝试 var http = require('http')
,但这会阻止 http.Server 被声明为返回值。
我应该如何使用 Mocks 在 Typescript 中实现单元测试?有没有比 mocky 更好的库?
【问题讨论】:
【参考方案1】:在网上搜索了一整天后,我终于了解到:是的,在 Mocha 测试中使用 Mockery 和 Typescript 有一个技巧。诀窍是使用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);
这让我可以像这样在我的 mocha 测试中设置模拟:
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找到其他一些可以用于依赖注入的场景。
【讨论】:
以上是关于使用 Typescript 在 Mocha 测试中使用 Mockery 有技巧吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何运行用 TypeScript 编写的 Mocha 测试?
Mocha 测试 TypeScript 奇怪的 TypeError
用于 TypeScript Mocha 测试的 Vscode 断点
使用 typescript/mocha 进行单元测试时找不到模块