Is there a trick for using Mockery in a Mocha test with Typescript?
The seemingly normal way of importing into typescript prevents the module from mocking ... Suppose I have the following product code in a node.js project written in typescript that I would like to test
// host.ts
import http = require('http');
export class Host {
public start(port: number): http.Server {
return http.createServer().listen(port);
}
}
I have below unit test using mockingery ( d.ts in pull request # 3313 ) and 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;
}
}
}
The problem is that when import webserver = require('../hosting/host')
called, the mocks in the test are not yet configured and non-mocked is returned require('http')
. I tried to try var http = require('http')
in a function Host.start
, but that prevents http.Server from being declared as a return value.
How do I make my unit tests implementation in typescript using Mocks? Is there a better library than mock that will perform better?
source to share
After a whole day of cleaning the web, I finally found out that: Yes, there is a trick using Mockery in Mocha test with Typescript. The trick is using an id typeof
to refer to a module. I discovered this in additional module downloads and other advanced load scripts in this document .
My updated code now looks like this:
// 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);
}
}
This allows me to set up mocks in my mock test like this:
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);
});
});
});
Some other scripts where this can be used for dependency injection can be found here .
source to share