Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setting up TypeScript unit tests with Mocha

I am trying to organize a new typescript project that has unit tests, also written in TS, running in the Mocha test runner.

My project with the following directory convention:

/project/src/             for server-side code (java)
/project/test/            server's tests
/project/resources/       client-side code (typescript)
/project/test-resources/  typescript tests. 

right now I have a typescript module Schema in a typescript file located at resources/many/levels/schema.ts

and I have its test, written for the mocha test runner, in a typescript file: test-resources/many/levels/schemaTest.ts

The problem is that the typescript compiler can't find the schema module using the following import syntaxes:

TC2307 Can't find module schema

schemaTest.ts (version 1):

/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/chai/chai.d.ts" />
/// <reference path="../../../resources/many/levels/schema.ts" />
import s = require('schema');

schemaTest.ts (version 2):

/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/chai/chai.d.ts" />
/// <reference path="../../../resources/many/levels/schema.ts" />
import {Schema, SchemaFactory} from 'schema';

finally, the following version compiles but leads to a runtime error since the module is not at ../../../resources/many/level but instead is located in the dist directory

/// <reference path="../typings/mocha/mocha.d.ts" />
/// <reference path="../typings/chai/chai.d.ts" />
/// <reference path="../../../resources/many/levels/schema.ts" />
import {Schema, SchemaFactory} from '../../../resources/many/levels/schema';

schema.ts:

module Schema  {

    export interface Schema {
        getName() : string;
        getColumnByIndex(index : number) : Column;
        getColumnById(id : string) : Column;
        getNumberOfColumns(): number;
    }

    export class SchemaFactory{
        ...
        build() : Schema {...}
    }
}  

I am compiling both my test and src files to a single dist directory (not ideal) and hope to run tests from there.

I am compiling with the flag --module commonjs.

if it matters, I am using IntelliJ 15 / WebStorm (and using its plugings for mocha, node, and tsc)

Is my Schema module set up incorrectly? Should it be an internal/external module? Should my tests be in the same namespace?

Thanks in advance!

like image 900
mcverry Avatar asked Jan 12 '16 16:01

mcverry


People also ask

Can I use Mocha with TypeScript?

ts-mocha is a wrapper on top of mocha to allow running tests written in TypeScript without setting up a complicated setup in your project, it just works. All mocha features are available without any limitation because ts-mocha is passing all the params to original mocha behind the scenes.

How do you do unit tests in TypeScript?

For TypeScript, unit tests are run against the generated JavaScript code. In most TypeScript scenarios, you can debug a unit test by setting a breakpoint in TypeScript code, right-clicking a test in Test Explorer, and choosing Debug.


1 Answers

I have been through these problems when I was setting up my jasmine tests but fundamentally the concepts are the same. The problem stems from the fact that while the relative path reference is specified based on the locations of the .ts files, that relative path reference is not maintained when the code is compiled over to the dist location. Below is how I got past that issue.

  1. Separate the compilation of scripts and specs into two different tasks. I am using gulp tasks for my build process but if you are not using gulp, you can still achieve this by having a separate tsconfig.json, one in resources folder for your source code compilation and another tsconfig.json in your resources-test folder for your test scripts compilation. Basically that would logically separate your source code and test scripts as two different typescript projects.

  2. For the typescript compilation of your source code, use the declaration compiler option set to true so that you get a schema.d.ts file. This file is going to be referenced in your schemaTest.ts. To make things super easy, have a build step that when source is compiled, copy over the .d.ts and .js files generated from the source compilation to a specific folder in the test-resources folder (lets say test-resources/compiledsource). The compiledsource folder will in this case have schema.d.ts and schema.js files.

The import statement in your test scripts (schematests.ts) will import from the compiledsource folder as below

import {Schema, SchemaFactory} from './compiledsource/schema';

  1. Your source compilation and test scripts compilation should be done in two steps and the first step would be source compilation so that when your test scripts compile, you have the schema.d.ts available in the compiledsource folder, and when your tests run the schema.js will be available in compiledsource folder.

When typescript interprets "import" statement, it will look for the .ts or .d.ts file and when it is compiled to javascript require statement, it will look for the .js file.

like image 171
Seshu Kumar Alluvada Avatar answered Oct 17 '22 23:10

Seshu Kumar Alluvada