NestJS中的模拟公牛队列



我正在尝试测试,在向我的一个控制器发送请求后,队列会推送作业。实现本身如预期的那样工作。

这是我的应用程序模块.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 {}

这就是我的import.module.ts(使用队列的模块(的样子:

    @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 {}

我试着采用这种方法

它没有在beforeAll钩子中注册队列,我得到了

     Driver not Connected

这种方法

它在测试套件的beforeAll钩子中注册了一个队列,我得到了:

     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>)

这是我的"基本测试套件":

    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();
      });
    });

知道这里可能出了什么问题吗?

我也遇到了同样的问题,问题出在您的mockQueue上。您需要添加一个process模拟函数。

这应该对你有用!

const importQueue: any = { 
  add: jest.fn(),
  process: jest.fn(),
};

我就是这样测试的。

expect(mockQueue.add).toBeCalledTimes(1);
      expect(mockQueue.add).nthCalledWith(
        1,
        PendoJobNames.SCR,
        {
          ...mockJobDto,
        },
        {
          jobId: mockDto.visitorId,
          removeOnComplete: true,
          removeOnFail: true,
        },
      );
    ```

我发现了一种简单的方法,可以使用包@golevelup/ts-jest中的createMock函数对类或接口进行深度模拟,该函数与NestJS依赖注入配合良好。

  let someController: SomeController;
  let someService: DeepMocked<SomeService>;
  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [SomeModule],
      controllers: [SomeController],
      providers: [
        {
          provide: SomeService,
          useValue: createMock<SomeService>(),
        },
        { provide: getConnectionToken(), useValue: createMock<Connection>() },
        { provide: getQueueToken('queueName'), useValue: createMock<Queue>() },
      ],
    }).compile();
    someController = moduleRef.get<SomeController>(SomeController);
    someService = moduleRef.get(SomeService);
  });
import { createMock } from "@golevelup/ts-jest";
import { getQueueOptionsToken, getQueueToken } from "@nestjs/bullmq";
import { Test } from "@nestjs/testing";
import { Queue, QueueOptions } from "bullmq";
describe("SomeModule", () => {
  let module: SomeModule;
  beforeEach(async () => {
    const testingModule = await Test.createTestingModule({
      imports: [
        /* ... */
      ],
    })
      .overrideProvider(getQueueOptionsToken())
      .useValue(createMock<QueueOptions>())
      .overrideProvider(getQueueToken("yourQueueName"))
      .useValue(createMock<Queue>())
      .compile();
    module = testingModule.get(SomeModule);
  });
  it("can be instantiated by Nest", () => {
    expect(module).toBeDefined();
  });
});

@moogs的答案是正确的,但我还必须添加另一个函数。

const queueMock = {
  add: jest.fn(),
  process: jest.fn(),
  on: jest.fn()
};

on函数,并且它起作用了。

相关内容

  • 没有找到相关文章

最新更新