https://github.com/unlight/awaitable-emit
Emit message to kafka and wait while nestjs process it
https://github.com/unlight/awaitable-emit
end-to-end-testing kafka microservices nestjs nestjs-testing testing
Last synced: 4 months ago
JSON representation
Emit message to kafka and wait while nestjs process it
- Host: GitHub
- URL: https://github.com/unlight/awaitable-emit
- Owner: unlight
- Created: 2024-12-31T19:13:15.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2025-01-01T15:00:18.000Z (over 1 year ago)
- Last Synced: 2025-09-13T04:39:37.551Z (9 months ago)
- Topics: end-to-end-testing, kafka, microservices, nestjs, nestjs-testing, testing
- Language: TypeScript
- Homepage:
- Size: 16.6 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## awaitable-emit
Emit message to kafka and wait while nestjs process it.
### How it works
Create helper utils for end to end test:
- `emitMessage` - function to emit message to kafka
- `AwaitableEmitInterceptor` - nestjs global interceptor (required for emitMessage)
- `dispose` - function to run on test tear down stage
### Usage
1. Create helper objects
```ts
const { emitMessage, AwaitableEmitInterceptor, dispose } = createAwaitableEmit(options)`
```
2. Add interceptor to nestjs app
```ts
app.useGlobalInterceptors(new AwaitableEmitInterceptor());
```
3. Use `emitMessage` in test
4. Run `dispose` in 'after all' stage
### Options
`getKafkaClient: () => ClientKafka` Factory function which returns kafka client instance
`wait?: number` Wait time in milliseconds (if controller cannot handle message in this time, promise will be resolved)
`brokers?: string[]` Kafka brokers, this is optional and uses kafka admin under the hood - waits when all consumners groups will have no lag
(this may or may not be useful for parallel running tests)
### Example
```ts
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@EventPattern('user-created')
async handleEntityCreated(@Payload() payload: object) {
console.log('user created', payload);
await setTimeout(2000); // Imitate long running process
this.appService.shared.push(payload);
}
}
```
```ts
describe('AppController (e2e)', () => {
let app: INestMicroservice;
let clientKafka: ClientKafka;
let service: AppService;
const { emitMessage, AwaitableEmitInterceptor, dispose } =
createAwaitableEmit({
getKafkaClient: () => clientKafka,
});
// Before all
before(async () => {
const providers: Provider[] = [
{
provide: 'KAFKA_CLIENT',
useFactory: () => {
return ClientProxyFactory.create({
transport: Transport.KAFKA,
options: {
client: {
clientId: 'KAFKA_CLIENT',
brokers: ['127.0.0.1:9092'],
},
},
});
},
},
];
const testingModule = await Test.createTestingModule({
imports: [AppModule],
providers,
}).compile();
app = testingModule.createNestMicroservice({
transport: Transport.KAFKA,
options: {
client: {
clientId: 'KAFKA_CLIENT',
brokers: ['127.0.0.1:9092'],
},
},
});
app.useGlobalInterceptors(new AwaitableEmitInterceptor());
await app.init();
await app.listen();
clientKafka = app.get('KAFKA_CLIENT');
service = app.get(AppService);
});
// After all
after(async () => {
await dispose();
await clientKafka?.close();
await app?.close();
});
it('smoke', () => {
expect(clientKafka).toBeTruthy();
});
it('test emit message', async () => {
await emitMessage('user-created', {
key: Date.now.toString(),
value: { name: 'Bob' },
});
expect(service.shared.at(-1)).toEqual({ name: 'Bob' });
});
});
```