在使用Typescript的Mocha测试中使用Mockery有诀窍吗?

时间:2014-12-13 17:28:42

标签: node.js unit-testing typescript mocha

看起来通常在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中实现单元测试?是否有更好的图书馆而不是嘲弄哪个更好?

1 个答案:

答案 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找到可以用于依赖注入的其他一些场景。