jestでdynamoが絡んだテストをするとき、次のテストケースに前のテストケースで生成したテストデータが残ったままになってしまう問題の改善


今までの方法

今作っているテストコードでは、テストケースごとにテストデータの生成と削除を行う。
そのテストケースが何十個もあるので、テストデータの生成と削除を多く繰り返していることになる。

そのせいか、一つ前のテストケースで削除したはずのテストデータが次のテストケース実行時にそのデータが残ったままで意図する期待値にならずテストが失敗となってしまう。。。

ただ計算するだけみたいなテストなら特に何も意識する必要はないが、
DBや外部APIやその他重い処理が絡むと、テスト時間が長かったり意図しない結果になる場合があるのではないだろうか。

もしjestのテスト実行を並列実行で行っている場合は以下の方法が有効になります。
テストにめっちゃ時間がかかる代わりに直列実行を選べば以下の方法は不要です。

方法

ググりまくったら、jestには「done」というものが利用でき、これをテストケースの引数に用意した場合は、このdoneを呼ぶまで次のテストケースを呼ぶのを待ってくれるらしい。
ここで、注意なのが、そのまま一番下にdone()を書くだけだと、非同期のせいでdone()が先に呼ばれてしまって結局意味ないことになってしまう。

dynamoでgetやputする際は、get(パラメータ).promise()するべきだが、このpromise()にthenをつけてこの中でdone()する。

anime-suko.ts
const testCase1 = test('hogehogeテスト', async (done) => {
//いろいろテスト(省略)

//ここから後処理
  await documentClient
    .delete(パラメータ)
    .promise()
    .then(() => {
      done()
    })
})

注意

引数にdoneを用意したら、必ず使う必要がある。
以下のように、引数にdoneを用意だけしてdone()して呼ばなかった場合、永遠に次のテストケースが呼ばれずタイムアウトになる。
doneは、引数に用意したときだけ待ってくれる機能が有効になるので、用意したら必ず使う。

anime-suko.ts
const testCase1 = test('hogehogeテスト', async (done) => {
//いろいろテスト(省略)

//ここから後処理
  await documentClient.delete(パラメータ).promise()
})

感想

jestで複数のテストファイルを一括で実行していて、今まではテストケース割と少なめだったから成功していたが、今回テストケース多めのテストコードを書いてたおかげで、今まで書いていた方法では安定しない方法だったと気づかされた。