【发布时间】:2020-12-05 06:50:12
【问题描述】:
背景
我最近了解了CLASP,并对使用TDD 在本地编辑我的Google Apps Scripts (GAS) 的可能性感到兴奋。
注意:可能有一种方法可以使用现有的 GAS 编辑器编写测试,但如果可能的话,我更喜欢使用现代编辑器
clasp 效果很好,但我不知道如何模拟单元测试的依赖项(主要通过jest,尽管我很乐意使用任何有效的工具)
- 我使用gas-local 包走得最远,并且能够在测试中模拟单个依赖项
- 但是我找不到在单个测试/调用中模拟多个依赖项的方法,因此我创建了this issue
挑战
尽管安装了@types/google-apps-script,但我不清楚如何分别使用 ES5 或 ES2015 语法“要求”或“导入”Google Apps 脚本模块——请参阅下面的说明。
相关 StackOverflow 帖子
虽然在单元测试here 上存在类似的 SO 问题,但大部分内容/cmets 似乎都来自 pre-clasp 时代,我在跟进剩余线索时无法找到解决方案。 (当然,我未经训练的眼睛很可能错过了什么!)。
尝试
使用本地气体
如上所述,我在使用 gas-local 时尝试模拟多个依赖项后创建了一个问题(参见上面的链接)。我的配置类似于我在下面描述的jest.mock 测试,但值得注意的是以下差异:
- 我使用 ES5 语法进行
gas-local测试 - 我的包配置可能略有不同
使用 jest.mock
LedgerScripts.test.js
import { getSummaryHTML } from "./LedgerScripts.js";
import { SpreadsheetApp } from '../node_modules/@types/google-apps-script/google-apps-script.spreadsheet';
test('test a thing', () => {
jest.mock('SpreadSheetApp', () => {
return jest.fn().mockImplementation(() => { // Works and lets you check for constructor calls
return { getActiveSpreadsheet: () => {} };
});
});
SpreadsheetApp.mockResolvedValue('TestSpreadSheetName');
const result = getSummaryHTML;
expect(result).toBeInstanceOf(String);
});
LedgerScripts.js
//Generates the summary of transactions for embedding in email
function getSummaryHTML(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dashboard = ss.getSheetByName("Dashboard");
// Do other stuff
return "<p>some HTML would go here</p>"
}
export default getSummaryHTML;
结果(运行jest 命令后)
Cannot find module '../node_modules/@types/google-apps-script/google-apps-script.spreadsheet' from 'src/LedgerScripts.test.js'
1 | import { getSummaryHTML } from "./LedgerScripts.js";
> 2 | import { SpreadsheetApp } from '../node_modules/@types/google-apps-script/google-apps-script.spreadsheet';
| ^
3 |
4 | test('test a thing', () => {
5 | jest.mock('SpreadSheetApp', () => {
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:307:11)
at Object.<anonymous> (src/LedgerScripts.test.js:2:1)
作为参考,如果我转到具有所需类型的 google-apps-script.spreadsheet.d.ts 文件,我会在文件顶部看到以下声明...
declare namespace GoogleAppsScript {
namespace Spreadsheet {
...和文件底部的这个:
declare var SpreadsheetApp: GoogleAppsScript.Spreadsheet.SpreadsheetApp;
所以也许我只是错误地导入了SpreadsheetApp?
其他文件
jest.config.js
module.exports = {
clearMocks: true,
moduleFileExtensions: [
"js",
"json",
"jsx",
"ts",
"tsx",
"node"
],
testEnvironment: "node",
};
babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
package.json
{
"name": "ledger-scripts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {
"@babel/core": "^7.11.1",
"@babel/preset-env": "^7.11.0",
"@types/google-apps-script": "^1.0.14",
"@types/node": "^14.0.27",
"babel-jest": "^26.3.0",
"commonjs": "0.0.1",
"eslint": "^7.6.0",
"eslint-plugin-jest": "^23.20.0",
"gas-local": "^1.3.1",
"requirejs": "^2.3.6"
},
"devDependencies": {
"@types/jasmine": "^3.5.12",
"@types/jest": "^26.0.9",
"jest": "^26.3.0"
}
}
【问题讨论】:
-
TheMaster:太酷了!只要像@dwmorrin 建议的方法那样工作,那么我可能会很好地在控制台中获得我的结果。但如果我想在浏览器中查看结果,我会记住
gunitgs2:)
标签: unit-testing google-apps-script jestjs tdd clasp