背景
オブジェクト配列をソートするメソッドを作成し、
そのユニットテストを書く。
Jestを利用したユニットテストで、
まずは失敗するように書こうと思った。
ソートするメソッド
function compare (a: Hoge, b: Hoge) {
if (a.fuga < b.fuga ) {
return -1
} else if (a.fuga > b.fuga) {
return 1
} else {
return 0
}
}
export default (objectList: Hoge[]): Hoge[] => {
return objectList.sort(compare)
}
ユニットテスト
describe('sort', () => {
test('false case', () => {
const baseArray = [ソート元のオブジェクト配列]
const sortArray = sortMethod(baseArray)
// ソート順を確認するためループ内で比較
sortArray.forEach((object, i) => {
expect(object).toEqual(baseArray[i])
}
});
});
しかし、これだとテストが成功してしまった。
原因
Array.sortはソートされた同じ配列の参照を返す。
そのためbaseArray
とsortArray
は参照先が同一となり、
中身はソートされた後の配列になっているため、
テスト結果がtrueになってしまう。
対処
ディープコピーを実施する。
ここではstructuredClone()
を使用する。
(使用できない環境であればJSON.parse(JSON.stringfy())
を使用するといい)
describe('sort', () => {
test('false case', () => {
const baseArray = [ソート元のオブジェクト配列]
// ソート結果をディープコピーする
const deepCopySortArray = structuredClone(sortMethod(baseArray))
deepCopySortArray.forEach((object, i) => {
expect(object).toEqual(baseArray[i])
}
});
});
これでテストが失敗することが確認できた。
結論
Array.sort()
は参照を返すため、それを意識して使用すること。