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?

+3


source to share


1 answer


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 .

+5


source







All Articles