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
}