I am trying to test that after sending a request to one of my controllers, the queue pushes a job. The implementation itself works as expected.
This is my app.module.ts
@Module({
imports: [
HttpModule,
TypeOrmModule.forRoot(typeOrmConfig),
BullModule.forRoot({
redis: {
host: redisConfig.host,
port: redisConfig.port,
},
}),
// Bunch of unrelated modules
],
providers: [
{
provide: APP_FILTER,
useClass: AllExceptionsFilter,
},
],
controllers: [SomeControllers],
})
export class AppModule {}
And this is how my import.module.ts (module using queues) looks like:
@Module({
imports: [
BullModule.registerQueue({
name: importQueueName.value,
}),
//More unrelated modules,
],
providers: [
//More services, and bull consumer and producer,
ImportDataProducer,
ImportDataConsumer,
ImportDataService,
],
controllers: [ImportDataController],
})
export class ImportDataModule {}
I tried to follow this approach
Which does not register the queue in the beforeAll hook, and I'm getting
Driver not Connected
And this approach
Which registers a queue in the beforeAll hook in the test suite, and I am getting:
TypeError: Cannot read properties of undefined (reading 'call')
at BullExplorer.handleProcessor (node_modules/@nestjs/bull/dist/bull.explorer.js:95:23)
at MapIterator.iteratee (node_modules/@nestjs/bull/dist/bull.explorer.js:59:26)
at MapIterator.next (node_modules/iterare/src/map.ts:9:39)
at FilterIterator.next (node_modules/iterare/src/filter.ts:11:34)
at IteratorWithOperators.next (node_modules/iterare/src/iterate.ts:19:28)
at Function.from (<anonymous>)
at IteratorWithOperators.toArray (node_modules/iterare/src/iterate.ts:227:22)
at MetadataScanner.scanFromPrototype (node_modules/@nestjs/core/metadata-scanner.js:12:14)
at node_modules/@nestjs/bull/dist/bull.explorer.js:56:34
at Array.forEach (<anonymous>)
This is my 'base test suite':
describe('Queue test suite', () => {
let app: INestApplication;
const importQueue: any = { add: jest.fn() };
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule, ImportDataModule],
})
.overrideProvider(importQueueName.value)
.useValue(importQueue)
.compile();
app = moduleFixture.createNestApplication();
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
}),
);
await app.init();
});
afterAll(async () => {
await app.close();
});
test('A job should be pushed', async () => {
await request(app.getHttpServer())
.post('/some/route')
.attach('file', __dirname + '/some.file')
.expect(HttpStatus.CREATED);
expect(importQueue.add).toHaveBeenCalled();
});
});
Any idea what could be wrong here?
I had the same issue, the problem is with your mockQueue
. You need to add a process
mocked function.
This should work for you!
const importQueue: any = {
add: jest.fn(),
process: jest.fn(),
};
And this is how I tested it.
expect(mockQueue.add).toBeCalledTimes(1);
expect(mockQueue.add).nthCalledWith(
1,
PendoJobNames.SCR,
{
...mockJobDto,
},
{
jobId: mockDto.visitorId,
removeOnComplete: true,
removeOnFail: true,
},
);
```