2

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   
  }
}

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the answer. I tried to do so from the beginning, but changing my my imports result in > error TS2497: Module '"/Users/.../NotificationService/test/node_modules/@types/chai-http/index"' resolves to a non-module entity and cannot be imported using this construct.
And using that import for express result in error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof e' has no compatible call signatures. 4 const app = express();
my bad, chai-http apparently can't be used with import. I tried it locally. I'm really curious with your express. I tried to reproduce it but I couldn't. May you posted your tsconfig.json?
I updated my question to include it. I also may upload the whole project excluding node_modules if you want.
@CodingVampyre Thank you. Try to remove your esModuleInterop from tsconfig.json. Using this setting doesn't allow you to use syntax import * as ... from ...
|
1

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.

1 Comment

I did both, but the error remains and nothing in the behaviour changes. Running the server still works fine, but testing still results in above error.
-1

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.