syntropylog
Version:
An instance manager with observability for Node.js applications
137 lines (131 loc) ⢠5.09 kB
JavaScript
/**
* MockBrokerAdapter - Framework Agnostic Mock
*
* This mock provides a testing-agnostic version of IBrokerAdapter
* that can be used with both Vitest and Jest without conflicts.
*/
/**
* Creates a simple agnostic mock function without spy capabilities
*/
function createAgnosticMockFn(implementation) {
const mockFn = (...args) => {
if (implementation) {
return implementation(...args);
}
return undefined;
};
// Basic mock properties
mockFn.mockClear = () => { };
mockFn.mockReset = () => { };
mockFn.mockImplementation = (impl) => {
return createAgnosticMockFn(impl);
};
mockFn.mockReturnValue = (value) => {
return createAgnosticMockFn(() => value);
};
mockFn.mockResolvedValue = (value) => {
return createAgnosticMockFn(() => Promise.resolve(value));
};
mockFn.mockRejectedValue = (value) => {
return createAgnosticMockFn(() => Promise.reject(value));
};
return mockFn;
}
export class MockBrokerAdapter {
spyFn = null;
errors = new Map();
timeouts = new Map();
// Core methods - will be initialized in constructor
connect;
disconnect;
publish;
subscribe;
setError;
setTimeout;
reset;
constructor(spyFn) {
this.spyFn = spyFn || null;
// Initialize mocks after spyFn is set
this.connect = this.createMock().mockImplementation(async () => {
// Check for timeout first
if (this.timeouts.has('connect')) {
await new Promise((resolve) => setTimeout(resolve, this.timeouts.get('connect') + 10));
throw new Error(`Mock broker timed out after ${this.timeouts.get('connect')}ms`);
}
// Check for error simulation
if (this.errors.has('connect')) {
throw this.errors.get('connect');
}
return undefined;
});
this.disconnect = this.createMock().mockImplementation(async () => {
if (this.timeouts.has('disconnect')) {
await new Promise((resolve) => setTimeout(resolve, this.timeouts.get('disconnect') + 10));
throw new Error(`Mock broker timed out after ${this.timeouts.get('disconnect')}ms`);
}
if (this.errors.has('disconnect')) {
throw this.errors.get('disconnect');
}
return undefined;
});
this.publish = this.createMock().mockImplementation(async (topic, message) => {
if (this.timeouts.has('publish')) {
await new Promise((resolve) => setTimeout(resolve, this.timeouts.get('publish') + 10));
throw new Error(`Mock broker timed out after ${this.timeouts.get('publish')}ms`);
}
if (this.errors.has('publish')) {
throw this.errors.get('publish');
}
return undefined;
});
this.subscribe = this.createMock().mockImplementation(async (topic, handler) => {
if (this.timeouts.has('subscribe')) {
await new Promise((resolve) => setTimeout(resolve, this.timeouts.get('subscribe') + 10));
throw new Error(`Mock broker timed out after ${this.timeouts.get('subscribe')}ms`);
}
if (this.errors.has('subscribe')) {
throw this.errors.get('subscribe');
}
return undefined;
});
this.setError = this.createMock().mockImplementation((method, error) => {
this.errors.set(method, error);
});
this.setTimeout = this.createMock().mockImplementation((method, timeoutMs) => {
this.timeouts.set(method, timeoutMs);
});
this.reset = this.createMock().mockImplementation(() => {
this.errors.clear();
this.timeouts.clear();
this.connect.mockReset();
this.disconnect.mockReset();
this.publish.mockReset();
this.subscribe.mockReset();
// Restore default implementations
this.connect.mockImplementation(async () => undefined);
this.disconnect.mockImplementation(async () => undefined);
this.publish.mockImplementation(async () => undefined);
this.subscribe.mockImplementation(async () => undefined);
});
}
createMock(implementation) {
if (!this.spyFn) {
throw new Error(`
šØ SPY FUNCTION NOT INJECTED! š”
To use spy functions like toHaveBeenCalled(), toHaveBeenCalledWith(), etc.
YOU MUST inject your spy function in the constructor:
// For Vitest:
const mockBroker = new MockBrokerAdapter(vi.fn);
// For Jest:
const mockBroker = new MockBrokerAdapter(jest.fn);
// For Jasmine:
const mockBroker = new MockBrokerAdapter(jasmine.createSpy);
// Without spy (basic functionality only):
const mockBroker = new MockBrokerAdapter();
DON'T FORGET AGAIN! š¤
`);
}
return this.spyFn(implementation);
}
}
//# sourceMappingURL=MockBrokerAdapter.js.map