JavaScript
Node.js
supertest

[nodejs] supertestのendは使わなくてもよい

supertestのREADMEを読むと、リクエスト実行の最後にend()関数でエラーを処理したり、expectの第二引数にdoneを渡してやるみたいなことが書かれていて、あまり深く考えずにそのまま書いていたのですが、doneを使わずにPromiseを返すように書きたいので何とかできないか色々やってみました。

test/test.js
describe('GET /users', () => {
  it('respond with json', done => {
    request(app)
      .get('/users')
      .expect(200)
      .end(function(err, res) {    // この辺がうっとうしい
        if (err) return done(err)  // この辺がうっとうしい
        assert.ok()
        done()                     // この辺がうっとうしい
      })
  })
})

READMEをちょっとスクロールしたら Promise support って書いてあったので普通にいけそうです。
こんな感じになりました。

test/test.js
describe('GET /users', () => {
  it('respond with json', () => 
    request(app)
      .get('/users')
      .expect(200)
      .then(res => {
        assert.ok()
      })
  )
})

supertestが返すTestオブジェクト

supertestで使う.get()とか.expect()みたいな関数は、supertestで実装されているTestというクラスのインスタンスを返します。
これ自体はPromiseではないのですが、thencatchを実装していてPromiseを返してくれます。さらにこのPromiseが、内部でend()を実行してくれて、エラーが発生したときにはreject(err)してくれるので、こっちを使ったほうがスッキリ書けていい感じです。

独自の例外処理

あまり思いつかないですが、どうしても独自の例外処理を書く必要が出てきた場合は、catchに書けば実行されます。
ただし、エラーを投げないと、例外発生時にもテストが正常終了してしまうので注意です。

test/test.js
describe('GET /users', () => {
  it('respond with json', () => 
    request(app)
      .get('/users')
      .expect(200)
      .then(res => {
        assert.ok()
      }).catch(err => {
        console.error(err)
        throw err
      })
  )
})
  • node 9.4.0
  • supertest 3.0.0
  • superagent 3.8.2