JavaScriptのcallbackをstub/mock化できるようにしたいのでbind(this)する

まとめ

JavaScript の callback メソッドを testable にしたい。

  • testable にするには独立して呼べることが大事。つまり独立メソッドにし、名前をつけることが必要。
  • 独立メソッドを callback として渡すにはリファレンスにする
  • リファレンスとして渡されたものは実行時に this が決定するのでそのまま実行すると同じ class 内でも this を見失う
  • リファレンスを bind(this) しておこう

this.method(val, function(err, res) {
  ..
})

みたいなコードはクロージャの中だけをテストすることができないからやめたい。じゃあこれを独立した callback メソッドにするとどうなるか。

this.method(val, this.callback)

これは callback メソッドのリファレンスを渡している形。これで必要な引数は自動的に渡るようになる。

このために method の中身は以下のようになっている。

method (val, cb) {
  ..
  cb(err, res)
  ..
}

これをそのまま実行すると callback は this を見失う。this は lexical scope ではなく dynamic に実行時に bind される。this を共有するには this を与える必要がある。

つまり正解はこう。

this.method(val, this.callback.bind(this))

arrow function を挟んで以下のようにすることもできるが、冗長だし、間違えそうなので避けたい。引数の数が少なく、名前も短いうちは読みやすいとは思うけど。

this.method(val, (err, res) => {
  this.callback(err, res)
})

More