Coding Vampyre
Coding Vampyre

Reputation: 93

Typescript, Express, Mocha & Chai Error while testing

I made my first server using express in typescript and it perfectly works

import app from './Server'

const server = app.listen(8080, '0.0.0.0', () => {
    console.log("Server is listening on standard port 80...");
});

export default server;

Now I try testing the routes stored in app:

import express from 'express';
import * as bodyParser from "body-parser";

const app = express();

app.use(bodyParser.json());

app.get("/", (req: express.Request, res: express.Response) => {
    res.status(200).send("SUCCESS");
});

export default app;

Using this test:

import * as chai from 'chai';
import chaiHttp = require('chai-http');

chai.use(chaiHttp);

import server from '../src';

describe("LogAPI", () => {

    describe('Base express tests', () => {
        it("Should return 'SUCCESS' if GET /", async () => {
            return chai.request(server).get("/").then(res => {
                chai.expect(res.body).to.equal("SUCCESS");
            })
        });

        it("Should return status-code 200 by calling GET /", async () => {
            return chai.request(server).get("/").then(res => {
                chai.expect(res.status).to.equal(200);
            })
        });

    });
});

But even while running the server itself works, staring the test with

mocha --require ts-node/register ./../test/**/*.ts

throws me this error:

/Users/.../NotificationService/src/Server/index.js:5 var app = express_1.default(); ^ TypeError: express_1.default is not a function at Object. (/Users/.../NotificationService/src/Server/inde> x.js:5:28)

I am using es6 target and commonjs module. How can I properly test my server?

Update 1 I now fiddled a bit and it turned out that deleting the default() method from the compiled code resolved something.

Now, I get

/Users/.../NotificationService/test/node_modules/@types/chai-http/index.d.ts:13 import * as request from 'superagent'; SyntaxError: Unexpected token import

Update 2 My ts-config.json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs", 
    "outDir": "./../out“,
    "strict": true,
    "esModuleInterop": true   
  }
}

Upvotes: 2

Views: 3987

Answers (3)

Coding Vampyre
Coding Vampyre

Reputation: 93

The answer was to not use seperate package.json and tsconfig.json files. Thanks to deerawan, I now use

- tsconfig.json
- package.json
- src/
    - index.ts
- test/
    - test.ts

which resolves the issue!

Upvotes: -1

deerawan
deerawan

Reputation: 8443

The error related to express is because express doesn't use default export, so the correct way is

// src.js
import * as express from 'express'

Don't forget to install type definitions so Typescript can compile it smoothly such as

npm install @types/express --save-dev
npm install @types/body-parser --save-dev
npm install @types/chai-http --save-dev

Updated: I tried it locally with this tsconfig.json

// tsconfig.json
{
  "compilerOptions": {
      "module": "commonjs",
      "types": [
        "node",
        "mocha",
        "express"
      ],
      "target": "es5",
      "lib": [
        "es2015"       
      ],
      ...
  },
}

Using default export has caveat as described in https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html

Hope it helps

Upvotes: 3

Matt McCutchen
Matt McCutchen

Reputation: 30999

You are attempting a default import from express, but the module uses an export assignment. Either replace import express from 'express'; with import express = require('express'); or set the esModuleInterop compiler option to true in tsconfig.json.

Upvotes: 1

Related Questions