Skip to content

Commit

Permalink
feat(test): apply vitest
Browse files Browse the repository at this point in the history
  • Loading branch information
ssut committed Jul 12, 2024
1 parent 9fb9f8a commit 092357f
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 70 deletions.
21 changes: 21 additions & 0 deletions auto-imports.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const afterAll: typeof import('vitest')['afterAll']
const afterEach: typeof import('vitest')['afterEach']
const assert: typeof import('vitest')['assert']
const beforeAll: typeof import('vitest')['beforeAll']
const beforeEach: typeof import('vitest')['beforeEach']
const chai: typeof import('vitest')['chai']
const describe: typeof import('vitest')['describe']
const expect: typeof import('vitest')['expect']
const it: typeof import('vitest')['it']
const suite: typeof import('vitest')['suite']
const test: typeof import('vitest')['test']
const vi: typeof import('vitest')['vi']
const vitest: typeof import('vitest')['vitest']
}
14 changes: 0 additions & 14 deletions e2e/jest-e2e.json

This file was deleted.

109 changes: 54 additions & 55 deletions e2e/module.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { Injectable } from '@nestjs/common';
import { Message, SQSClient } from '@aws-sdk/client-sqs';
import { Injectable } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { vi } from 'vitest';
import { beforeAll } from 'vitest';
import { describe } from 'vitest';
import { expect } from 'vitest';
import { afterAll } from 'vitest';
import { it } from 'vitest';
import { afterEach } from 'vitest';
import { SqsModule, SqsService } from '../lib';
import { SqsConsumerOptions, SqsProducerOptions } from '../lib/sqs.types';
import { SqsConsumerEventHandler, SqsMessageHandler } from '../lib/sqs.decorators';
import waitForExpect from 'wait-for-expect';
import { SqsConsumerOptions, SqsProducerOptions } from '../lib/sqs.types';

const SQS_ENDPOINT = process.env.SQS_ENDPOINT || 'http://localhost:9324';
const SQS_ENDPOINT = process.env.SQS_ENDPOINT || 'http://localhost:9324/000000000000';

enum TestQueue {
Test = 'test',
Expand All @@ -17,29 +23,25 @@ const sqs = new SQSClient({
apiVersion: '2012-11-05',
credentials: { accessKeyId: 'x', secretAccessKey: 'x' },
endpoint: SQS_ENDPOINT,
region: 'none',
region: 'us-west-2',
});

const TestQueues: { [key in TestQueue]: SqsConsumerOptions | SqsProducerOptions } = {
[TestQueue.Test]: {
name: TestQueue.Test,
queueUrl: `${SQS_ENDPOINT}/queue/test.fifo`,
queueUrl: `${SQS_ENDPOINT}/test.fifo`,
sqs,
},
[TestQueue.DLQ]: {
name: TestQueue.DLQ,
queueUrl: `${SQS_ENDPOINT}/queue/test-dead.fifo`,
queueUrl: `${SQS_ENDPOINT}/test-dead.fifo`,
sqs,
},
};

describe('SqsModule', () => {
let module: TestingModule;

describe.skip('register', () => {
//
});

describe('registerAsync', () => {
let module: TestingModule;

Expand Down Expand Up @@ -69,16 +71,15 @@ describe('SqsModule', () => {
});

describe('full flow', () => {
const fakeProcessor = jest.fn();
const fakeDLQProcessor = jest.fn();
const fakeErrorEventHandler = jest.fn();
const fakeProcessor = vi.fn();
const fakeDLQProcessor = vi.fn();
const fakeErrorEventHandler = vi.fn();

@Injectable()
class A {
public constructor(public readonly sqsService: SqsService) {}

@SqsMessageHandler(TestQueue.Test)
// eslint-disable-next-line @typescript-eslint/no-empty-function
public async handleTestMessage(message: Message) {
fakeProcessor(message);
}
Expand Down Expand Up @@ -127,8 +128,8 @@ describe('SqsModule', () => {
});

afterEach(() => {
fakeProcessor.mockRestore();
fakeErrorEventHandler.mockRestore();
fakeProcessor.mockReset();
fakeErrorEventHandler.mockReset();
});

afterAll(async () => {
Expand All @@ -146,18 +147,16 @@ describe('SqsModule', () => {
expect(sqsService.producers.has(TestQueue.Test)).toBe(true);
});

it('should call message handler when a new message has come', () => {
jest.setTimeout(30000);

it('should call message handler when a new message has come', async () => {
const sqsService = module.get(SqsService);
const id = String(Math.floor(Math.random() * 1000000));

return new Promise(async (resolve, reject) => {
await new Promise<void>(async (resolve, reject) => {
try {
fakeProcessor.mockImplementationOnce((message) => {
fakeProcessor.mockImplementation((message) => {
expect(message).toBeTruthy();
expect(JSON.parse(message.Body)).toStrictEqual({ test: true });
resolve(undefined);
resolve();
});

await sqsService.send(TestQueue.Test, {
Expand All @@ -171,53 +170,53 @@ describe('SqsModule', () => {
reject(e);
}
});
});
}, 5000);

it('should call message handler multiple times when multiple messages have come', async () => {
jest.setTimeout(5000);

const sqsService = module.get(SqsService);
const groupId = String(Math.floor(Math.random() * 1000000));

for (let i = 0; i < 3; i++) {
const id = `${groupId}_${i}`;
await sqsService.send(TestQueue.Test, {
id,
body: { test: true, i },
delaySeconds: 0,
groupId,
deduplicationId: id,
});
}
await Promise.all(
Array.from({ length: 3 }).map(async (_, i) => {
const id = `${groupId}_${i}`;
await sqsService.send(TestQueue.Test, {
id,
body: { test: true, i },
delaySeconds: 0,
groupId,
deduplicationId: id,
});
}),
);

await waitForExpect(
await vi.waitFor(
() => {
expect(fakeProcessor.mock.calls).toHaveLength(3);
for (const call of fakeProcessor.mock.calls) {
expect(call).toHaveLength(1);
expect(call[0]).toBeTruthy();
}
},
5000,
100,
{
interval: 100,
timeout: 5000,
},
);
});

it('should call the registered error handler when an error occurs', () => {
jest.setTimeout(10000);
}, 5500);

it('should call the registered error handler when an error occurs', async () => {
const sqsService = module.get(SqsService);
const id = String(Math.floor(Math.random() * 1000000));
fakeProcessor.mockImplementationOnce((message) => {
fakeProcessor.mockImplementation((_message) => {
throw new Error('test');
});

return new Promise(async (resolve, reject) => {
await new Promise<void>(async (resolve, reject) => {
try {
fakeErrorEventHandler.mockImplementationOnce((error, message) => {
fakeErrorEventHandler.mockImplementationOnce((error, _message) => {
expect(error).toBeInstanceOf(Error);
expect(error.message).toContain('test');
resolve(undefined);
resolve();
});

await sqsService.send(TestQueue.Test, {
Expand All @@ -231,18 +230,18 @@ describe('SqsModule', () => {
reject(e);
}
});
});
}, 5000);

it('should consume a dead letter from DLQ', async () => {
jest.setTimeout(10000);

await waitForExpect(
await vi.waitFor(
() => {
expect(fakeDLQProcessor.mock.calls.length).toBe(1);
},
9900,
500,
{
interval: 500,
timeout: 9900,
},
);
});
}, 10000);
});
});
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"outDir": "./dist",
"rootDir": "./lib",
"skipLibCheck": true,
"baseUrl": "./"
"baseUrl": "./",
"types": ["vitest/globals"]
},
"include": ["lib", "e2e"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
Expand Down
36 changes: 36 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import AutoImport from 'unplugin-auto-import/vite';
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
include: ['**/*.e2e-spec.ts'],
environment: 'node',
globals: true,
root: './',
testTimeout: 20000,
hookTimeout: 30000,
cache: false,
reporters: ['verbose'],
isolate: false,
maxConcurrency: 1,
pool: 'forks',
poolOptions: {
forks: {
isolate: false,
singleFork: true,
minForks: 1,
maxForks: 1,
},
},
},
plugins: [
// This is required to build the test files with SWC
// swc.vite({
// // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file
// module: { type: 'nodenext' },
// }),
AutoImport({
imports: ['vitest'],
}),
],
});

0 comments on commit 092357f

Please sign in to comment.