clasp + TypeScriptであることが前提
$ npm install -D @types/jest jest ts-jest
jest.config.js
module.exports = {
preset: 'ts-jest',
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)'],
globals: { SpreadsheetApp: {}, UrlFetchApp: {}, Utilities: {} },
}
globalsとは
GAS固有の型定義をmockするための設定
GAS上ではSpreadsheetAppが使えたりするが、ローカルで実行するときには当然存在しないため、window.SpreadsheetAppを定義している
メソッド数の多いinterfaceを実装するのは大変なので、 https://github.com/marchaos/jest-mock-extended などを使う
import { mock } from 'jest-mock-extended'
describe('test', () => {
const values = [
['Bob', new Date('2021-01-02T15:04:05')]
['Alice', new Date('2021-02-03T15:04:05')]
]
// SpreadsheetAppをmockする
const mockRange = mock<GoogleAppsScript.Spreadsheet.Range>()
mockRange.getValues.mockReturnValue(values)
const mockSheet = mock<GoogleAppsScript.Spreadsheet.Sheet>()
mockSheet.getRange.mockReturnValue(mockRange)
const mockSpreadsheet = mock<GoogleAppsScript.Spreadsheet.Spreadsheet>()
mockSpreadsheet.getSheetByName.mockReturnValue(mockSheet)
SpreadsheetApp.getActiveSpreadsheet = jest.fn(() => {
return mockSpreadsheet
})
// Utilitiesをmockする
Utilities.formatDate = jest.fn((date: Date) => {
return `${date.getFullYear()}-${date.getMonth() < 9 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1}-${
date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
}T${date.getHours() < 10 ? '0' + date.getHours() : date.getHours()}:${
date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
}:${date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()}`
})
const actual = doFormat()
expect(mockSheet.getRange).toHaveBeenCalledTimes(1)
expect(actual).toBe('2021-01-02T15:04:05')
}
export function doFormat() {
// sheetを取得
const mysheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('mysheet')
// セルの値を配列で取得
const values = mysheet.getRange(1, 1, 2, 2).getValues()
// 日付フォーマット
const formatted = Utilities.formatDate(values[0][1])
return formatted
}