背景
AWS-SDKをMockする記事はたくさん見つかるが、どれもとてもめんどくさく感じていた。もっと簡単に、できれば余分なパッケージとか使わないで、できるだけ簡単にMockしたい。
方針
- AWS-SDKは結局WebAPIへのラッパーで、内部構造は、services というオブジェクトの中に各メソッドが入っている。
- 汎用性を高めるために、servicesは日付でバージョニングされている。
- 各サービスオブジェクトをnewすると、最新のservicesが呼ばれる仕様。(古いAPIを各サービスのコンストラクタで指定することもできる)
これらの構造を逆手にとって、servicesの特定のメソッドを直接指定してMockingすれば他のメソッドに影響なく、ピンポイントでMockingすることができる。
コード例
AWS-SDKをシンプルにMockする。(例はLambda invoke)
APIバージョンは適当に切り替わるようにしとくとよいよね。
example.test.ts
import * as AWS from 'aws-sdk'
jest.spyOn(AWS.Lambda.services ["2015-03-31"].prototype, 'invoke').mockImplementation( (request) => {
return {promise: () => 'debug'}
})
多くの場合、promise()を呼んでると思うので、promise()メソッドを内包したオブジェクトを返してあげよう。
spyOnを使っているのは、jest.restoreAllMocksメソッドで簡単にMockをキャンセルできるようにするため。
これくらい簡単にMockできたら、テスタブルにするために、AWS-SDKをラップするクラスを作って、DI(Dependency Injection) する構造にしなくてもよい。使いたいときに使えばよくなる。