Skip to content

Commit 7da1929

Browse files
[Scheduler-test] add tests for ScraperScheduler
1 parent 9d9204f commit 7da1929

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

src/__tests__/shceduler.test.ts

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import cron from 'node-cron';
2+
import ScraperScheduler from '../Scheduler';
3+
import Main from '../main';
4+
5+
jest.mock('node-cron', () => ({
6+
schedule: jest.fn(),
7+
}));
8+
9+
jest.mock('../main', () => {
10+
return jest.fn().mockImplementation(() => {
11+
return { run: jest.fn().mockResolvedValue(undefined) };
12+
});
13+
});
14+
15+
describe('ScraperScheduler', () => {
16+
const cronExpression = '*/5 * * * *'; // Every 5 minutes
17+
let scheduler: ScraperScheduler;
18+
19+
beforeEach(() => {
20+
scheduler = new ScraperScheduler(cronExpression);
21+
});
22+
23+
afterEach(() => {
24+
jest.clearAllMocks();
25+
});
26+
27+
it('should initialize with a given cron expression', () => {
28+
expect((scheduler as any).cronExpression).toBe(cronExpression);
29+
expect((scheduler as any).task).toBeNull();
30+
});
31+
32+
it('should start the scheduler and set up a cron job', () => {
33+
const scheduleMock = cron.schedule as jest.Mock;
34+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
35+
36+
scheduler.start();
37+
38+
expect(scheduleMock).toHaveBeenCalledWith(
39+
cronExpression,
40+
expect.any(Function)
41+
);
42+
expect(consoleLogSpy).toHaveBeenCalledWith(
43+
`Scheduler started with cron expression: ${cronExpression}`
44+
);
45+
46+
scheduleMock.mockRestore();
47+
consoleLogSpy.mockRestore();
48+
});
49+
50+
it('should call the scrape method when the cron job is triggered', async () => {
51+
const scheduleMock = cron.schedule as jest.Mock;
52+
const scrapeSpy = jest.spyOn(scheduler, 'scrape').mockResolvedValue(undefined);
53+
54+
// Mock the cron.schedule to directly call the provided function
55+
scheduleMock.mockImplementation((_, callback) => {
56+
callback();
57+
return { stop: jest.fn() };
58+
});
59+
60+
await scheduler.start(); // Ensure `start` is awaited for asynchronous handling
61+
62+
expect(scrapeSpy).toHaveBeenCalled();
63+
64+
scheduleMock.mockRestore();
65+
scrapeSpy.mockRestore();
66+
});
67+
68+
it('should stop the scheduled cron job', () => {
69+
const stopMock = jest.fn();
70+
(scheduler as any).task = { stop: stopMock };
71+
72+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
73+
74+
scheduler.stop();
75+
76+
expect(stopMock).toHaveBeenCalled();
77+
expect(consoleLogSpy).toHaveBeenCalledWith('Scheduler stopped.');
78+
79+
stopMock.mockRestore();
80+
consoleLogSpy.mockRestore();
81+
});
82+
83+
it('should do nothing if stop is called when no task is scheduled', () => {
84+
const stopMock = jest.fn();
85+
86+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
87+
88+
scheduler.stop();
89+
90+
expect(stopMock).not.toHaveBeenCalled();
91+
expect(consoleLogSpy).not.toHaveBeenCalled();
92+
93+
consoleLogSpy.mockRestore();
94+
});
95+
96+
it('should handle errors in the scrape method gracefully', async () => {
97+
const scheduleMock = cron.schedule as jest.Mock;
98+
const error = new Error('Scraping error');
99+
const scrapeSpy = jest.spyOn(scheduler, 'scrape').mockRejectedValue(error);
100+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
101+
102+
scheduleMock.mockImplementation((_, callback) => {
103+
callback();
104+
return { stop: jest.fn() };
105+
});
106+
107+
await scheduler.start(); // Ensure `start` is awaited for asynchronous handling
108+
109+
await new Promise((resolve) => setImmediate(resolve)); // Allow time for async operations
110+
111+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error during scraping:', error);
112+
113+
scheduleMock.mockRestore();
114+
scrapeSpy.mockRestore();
115+
consoleErrorSpy.mockRestore();
116+
});
117+
});

0 commit comments

Comments
 (0)