LoginSignup
1
1

More than 3 years have passed since last update.

Express/Typescriptのルーティングテストが全てPassしてしまう対処法

Last updated at Posted at 2019-05-19

Express/TypescriptでAPIサーバーを構築しており

Jestとsupertestを用いてルーティングテストを作成しました。

その時、明らかにテストがfailするなずなのにpassしてしまう問題😭 があり、その原因を調べ対処しました。

補足

環境

  • Node: v10.15.2
    • nodeenvを利用し、プロジェクトごとにバージョンを指定することがおすすめです。
  • @types/jest: 24.0.11
  • @types/supertest: 2.0.7

Jest

  • Facebook製のjavascriptテストフレームワーク。
  • アサーションだけでなく、テストカバレッジなども行ってくれる万能ライブラリ。

supertest

  • Http通信のテストに特化したテストツール。

テスト対象のルーティング

app.ts
import * as express from 'express';

class App {

  public express: express.Application;

  constructor() {
    this.express = express();
    this.routes();
  }

  public routes() {
    // root('/')にGETメソッドでリクエストすると、status_code:200 で body:{message:"Hello Express!"} が返る
    this.express.get('/', (req, res) => res.json({message:"Hello Express!"}));
  }

  public start() {
    this.express.listen(3333, () => console.log(`Example app listening on port 3333!`));
  }
}

export default App;

○ 修正前

テスト

app.spec.ts

import * as request from "supertest";
import App from "../src/app";

describe("GET /", () => {
  it("return 200 and correct message", () => {
    const app = new App();
    request(app.express)
      .get("/")
      .expect(400) // あえてfailするテストを追加
      .expect({message: 'Hello Express!'});
  });
});

結果

$ yarn test
yarn run v1.15.2
$ jest
 PASS  test/app.spec.ts
  GET /
    ✓ return 200 (10ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.08s

テストがpassしてしまっている 😱。

問題

  • status_codeは200が返るのに、400を返すことを想定したテストでもpassしてしまいました。

  • 他のテストを書いていて気づいたのですが、status_code以外でも明らかにfailするテストを書いてもpassするようになっていました。

原因

How to test Express.js with Jest and Supertest

That return is crucial, otherwise your tests will get stuck.

'return'は非常に重要であり、さもなければあなたのテストは行き詰まる

Notice that without that return, the test will always pass.

returnを付けないと、必ずテストがpassしてしまう


supersetのテストの方法として、必ずステートメントを返す必要があり、
今回の場合はreturnがなく、何も返されていなかったため、全てのテストでpassすることになっっていました。

修正方法

expectedの値をreturnさせる。

○ 修正後

テスト

app.spec.ts
import * as request from "supertest";
import App from "../src/app";

describe("GET /", () => {
  it("return 200", () => {
    const app = new App();
    // 'return'を追加した
    return request(app.express)
      .get("/")
      .expect(400) // あえてfailするテストを追加
      .expect({ message: 'Hello Express!' });
  });
});

結果

$ yarn test
yarn run v1.15.2
$ jest  && tsc --noEmit
 FAIL  test/app.spec.ts (10.787s)
  GET /
    ✕ return 200 (47ms)

  ● GET / › return 200

    expected 400 "Bad Request", got 200 "OK"

      at Test.Object.<anonymous>.Test._assertStatus (node_modules/supertest/lib/test.js:268:12)
      at Test.Object.<anonymous>.Test._assertFunction (node_modules/supertest/lib/test.js:283:11)
      at Test.Object.<anonymous>.Test.assert (node_modules/supertest/lib/test.js:173:18)
      at Server.localAssert (node_modules/supertest/lib/test.js:131:12)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        11.801s
Ran all test suites.
error Command failed with exit code 1.

テストは想定通りfailするようになりました🙌

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1