- Create benchmark test suites for critical operations: - Node loading performance - Database query performance - Search operations performance - Validation performance - MCP tool execution performance - Add GitHub Actions workflow for benchmark tracking: - Runs on push to main and PRs - Uses github-action-benchmark for historical tracking - Comments on PRs with performance results - Alerts on >10% performance regressions - Stores results in GitHub Pages - Create benchmark infrastructure: - Custom Vitest benchmark configuration - JSON reporter for CI results - Result formatter for github-action-benchmark - Performance threshold documentation - Add supporting utilities: - SQLiteStorageService for benchmark database setup - MCPEngine wrapper for testing MCP tools - Test factories for generating benchmark data - Enhanced NodeRepository with benchmark methods - Document benchmark system: - Comprehensive benchmark guide in docs/BENCHMARKS.md - Performance thresholds in .github/BENCHMARK_THRESHOLDS.md - README for benchmarks directory - Integration with existing test suite The benchmark system will help monitor performance over time and catch regressions before they reach production. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
4.0 KiB
4.0 KiB
n8n-nodes-base Mock
This directory contains comprehensive mocks for n8n packages used in unit tests.
n8n-nodes-base Mock
The n8n-nodes-base.ts mock provides a complete testing infrastructure for code that depends on n8n nodes.
Features
-
Pre-configured Node Types
webhook- Trigger node with webhook functionalityhttpRequest- HTTP request node with mock responsesslack- Slack integration with all resources and operationsfunction- JavaScript code execution nodenoOp- Pass-through utility nodemerge- Data stream merging nodeif- Conditional branching nodeswitch- Multi-output routing node
-
Flexible Mock Behavior
- Override node execution logic
- Customize node descriptions
- Add custom nodes dynamically
- Reset all mocks between tests
Basic Usage
import { vi } from 'vitest';
// Mock the module
vi.mock('n8n-nodes-base', () => import('../__mocks__/n8n-nodes-base'));
// In your test
import { getNodeTypes, mockNodeBehavior, resetAllMocks } from '../__mocks__/n8n-nodes-base';
describe('Your test', () => {
beforeEach(() => {
resetAllMocks();
});
it('should get node description', () => {
const registry = getNodeTypes();
const slackNode = registry.getByName('slack');
expect(slackNode?.description.name).toBe('slack');
});
});
Advanced Usage
Override Node Behavior
mockNodeBehavior('httpRequest', {
execute: async function(this: IExecuteFunctions) {
return [[{ json: { custom: 'response' } }]];
}
});
Add Custom Nodes
import { registerMockNode } from '../__mocks__/n8n-nodes-base';
const customNode = {
description: {
displayName: 'Custom Node',
name: 'customNode',
group: ['transform'],
version: 1,
description: 'A custom test node',
defaults: { name: 'Custom' },
inputs: ['main'],
outputs: ['main'],
properties: []
},
execute: async function() {
return [[{ json: { result: 'custom' } }]];
}
};
registerMockNode('customNode', customNode);
Mock Execution Context
const mockContext = {
getInputData: vi.fn(() => [{ json: { test: 'data' } }]),
getNodeParameter: vi.fn((name: string) => {
const params = {
method: 'POST',
url: 'https://api.example.com'
};
return params[name];
}),
getCredentials: vi.fn(async () => ({ apiKey: 'test-key' })),
helpers: {
returnJsonArray: vi.fn(),
httpRequest: vi.fn()
}
};
const result = await node.execute.call(mockContext);
Mock Structure
Each mock node implements the INodeType interface with:
description: Complete node metadata including properties, inputs/outputs, credentialsexecute: Mock implementation for regular nodes (returnsINodeExecutionData[][])webhook: Mock implementation for trigger nodes (returns webhook data)
Testing Patterns
-
Unit Testing Node Logic
const node = registry.getByName('slack'); const result = await node.execute.call(mockContext); expect(result[0][0].json.ok).toBe(true); -
Testing Node Properties
const node = registry.getByName('httpRequest'); const methodProp = node.description.properties.find(p => p.name === 'method'); expect(methodProp.options).toHaveLength(6); -
Testing Conditional Nodes
const ifNode = registry.getByName('if'); const [trueOutput, falseOutput] = await ifNode.execute.call(mockContext); expect(trueOutput).toHaveLength(2); expect(falseOutput).toHaveLength(1);
Utilities
resetAllMocks()- Clear all mock function callsmockNodeBehavior(name, overrides)- Override specific node behaviorregisterMockNode(name, node)- Add new mock nodesgetNodeTypes()- Get the node registry withgetByNameandgetByNameAndVersion
See Also
tests/unit/examples/using-n8n-nodes-base-mock.test.ts- Complete usage examplestests/unit/__mocks__/n8n-nodes-base.test.ts- Mock test coverage