@ciderjs/vitest-plugin-gas-mock
v0.2.0
Published
Vitest plugin to mock Google Apps Script environment
Downloads
55
Readme
@ciderjs/vitest-plugin-gas-mock
Vitest plugin to mock Google Apps Script (GAS) environment.
Features
- Automatic Mocking: Dynamically generates mocks based on official
@types/google-apps-script. - Enum Support: Includes support for GAS enums (e.g.,
SpreadsheetApp.BorderStyle.SOLID). - Method Chaining: Supports GAS fluent APIs (e.g.,
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1')). - Global Injection: Automatically injects mocks into the global scope in tests.
mockChainHelper: Easily override return values for complex method paths.
Installation
pnpm add -D @ciderjs/vitest-plugin-gas-mockSetup
Add the plugin to your vitest.config.ts:
import { defineConfig } from 'vitest/config';
import { mockGas } from '@ciderjs/vitest-plugin-gas-mock';
export default defineConfig({
plugins: [mockGas()],
test: {
globals: true, // Required for global injection
},
});Usage
Basic Usage
Once configured, GAS services like SpreadsheetApp, DriveApp, etc., are available globally in your tests.
import { it, expect } from 'vitest';
it('should mock SpreadsheetApp', () => {
const ss = SpreadsheetApp.getActiveSpreadsheet();
expect(ss).toBeDefined();
const sheet = ss.getSheetByName('MySheet');
expect(sheet).toBeDefined();
});Overriding Return Values with mockChain
Use mockChain to set return values for specific method call paths.
import { it, expect } from 'vitest';
import { mockChain } from '@ciderjs/vitest-plugin-gas-mock';
it('should return specific value for a chain', () => {
const mockValue = "Hello from mock";
// Set the override
mockChain(
'SpreadsheetApp.getActiveSpreadsheet.getName',
mockValue
);
const name = SpreadsheetApp.getActiveSpreadsheet().getName();
expect(name).toBe(mockValue);
});Dynamic Return Values
You can pass a callback function to mockChain to determine the return value dynamically based on arguments.
mockChain('SpreadsheetApp.getActiveSpreadsheet.getSheetByName', (name) => {
if (name === 'Missing') {
return null;
}
// You can return a partial object (DeepPartial),
// so you don't need to implement all methods like `activate`, `copy`, etc.
return {
getName: () => name,
};
});Type Safety
The mockChain helper provides strict type inference:
- Path Validation: The path string (e.g.,
'SpreadsheetApp.getActiveSpreadsheet') is validated against GAS types. - Callback Arguments: Arguments in the callback function are automatically typed.
- Return Type: The return value is checked against the expected GAS type (supports
DeepPartialfor easier mocking).
How it works
The plugin performs the following steps:
- Analyze: Parses GAS type definitions to build a map of classes, methods, and return types.
- Generate: Creates a runtime map that identifies which methods are "chainable" (i.e., return another GAS class).
- Inject: Uses a Proxy-based factory to create spies (
vi.fn()) that automatically return new proxies for chainable methods.
Scripts
pnpm generate: Refreshes the internal GAS API map (runs automatically before build/test).pnpm build: Builds the plugin.pnpm test: Runs integration and unit tests.
License
MIT
