Nestjs循环依赖使用Jest

o7jaxewo  于 6个月前  发布在  Jest
关注(0)|答案(1)|浏览(73)

在一个使用mongoose的nestJs应用程序中,当应用程序运行时,我没有任何问题。但是我想使用jest编写单元测试,在这种情况下有一个问题。
我简化了代码,把重点放在了问题上,下面是我的测试文件:

// client.controller.spec.ts
import { Test } from '@nestjs/testing'
import { PrivateClientService } from '../client.service'
import { responseMock } from '@test/mocks/response.mock'

jest.mock('../client.service')

describe('PrivateClientController', () => {
  let privateClientService: PrivateClientService

  beforeEach(async () => {
    console.log(responseMock) // Import with alias works
    
    const moduleRef = await Test.createTestingModule({
      imports: [],
      // controllers: [],
      providers: [PrivateClientService],
    }).compile()
    jest.clearAllMocks()
  })

  describe('createClient', () => {
    it('should passed', () => {
      expect(true).toBe(true)
    })
  })
})

字符串
当我运行上面的测试时,我遇到了这个错误:

src/framework/features/client/private/test/client.controller.spec.ts
  PrivateClientController
    createClient
      ✕ should passed (14 ms)

  ● PrivateClientController › createClient › should passed

    A circular dependency has been detected inside RootTestModule. Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()". Note that circular relationships between custom providers (e.g., factories) are not supported since functions cannot be called more than once.

      18 |     console.log(responseMock)
      19 |     
    > 20 |     const moduleRef = await Test.createTestingModule({
         |                       ^
      21 |       imports: [],
      22 |       // controllers: [PrivateClientController],
      23 |       providers: [PrivateClientService],

      at NestContainer.addProvider (node_modules/@nestjs/core/injector/container.js:146:19)
      at DependenciesScanner.insertProvider (node_modules/@nestjs/core/scanner.js:235:35)
      at node_modules/@nestjs/core/scanner.js:119:18
          at Array.forEach (<anonymous>)
      at DependenciesScanner.reflectProviders (node_modules/@nestjs/core/scanner.js:118:19)
      at DependenciesScanner.scanModulesForDependencies (node_modules/@nestjs/core/scanner.js:99:18)
      at async DependenciesScanner.scan (node_modules/@nestjs/core/scanner.js:31:9)
      at async TestingModuleBuilder.compile (node_modules/@nestjs/testing/testing-module.builder.js:70:9)
      at async Object.<anonymous> (src/framework/features/client/private/test/client.controller.spec.ts:20:23)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.778 s, estimated 1 s


如果我注解了下面的行,测试就通过了。

// providers: [PrivateClientService],


所以,我的猜测是,它来自PrivateClientService,但经过大量的研究,我不明白或找到为什么。

// client.service.ts
import { Injectable, NotFoundException } from '@nestjs/common'
import { isValidObjectId } from 'mongoose'

import { InvalidObjectIdException } from '@framework/exceptions/InvalidObjectId.exception'

import { Client } from '../schemas/client.schema'
import { ClientRepository } from '../client.repository'

@Injectable()
export class PrivateClientService {
  constructor(private readonly clientRepository: ClientRepository) {}

  async createClient(client: Client): Promise<Client> {
    const newClient = await this.clientRepository.create(client)

    return newClient
  }

  async updateClient(id: string, client: Client): Promise<Client> {
    if (!isValidObjectId(id)) throw new InvalidObjectIdException()

    const updatedClient = await this.clientRepository.findByIdAndUpdate(id, client)

    if (!updatedClient) {
      throw new NotFoundException()
    }

    return updatedClient
  }

  async deleteClient(id: string): Promise<Client> {
    if (!isValidObjectId(id)) throw new InvalidObjectIdException()

    const client = await this.clientRepository.findByIdAndDelete(id)

    if (!client) {
      throw new NotFoundException()
    }

    return client
  }
}


我对nestjs/nodeJs很陌生,对于那些想知道我是否遵循这个repo architecture的人来说。
这时,我试着:

  • forwardRef PrivateClientService中的构造函数
  • 注解PrivateClientService中的client.schema和client.repository的两个导入
  • 我已经检查了导入别名是否工作正常(是)
  • 保持希望
ugmeyewa

ugmeyewa1#

我发现问题了

我认为jest mock行会自动使用__mocks__文件夹:

jest.mock('../client.service')

字符串
但在我的模拟里面有我的文件:

// __mocks__/client.service.ts
import { clientStub } from '../test/stubs/client.stub'

export const clientService = jest.fn().mockReturnValue({
  createClient: jest.fn().mockResolvedValue(clientStub()),
  updateClient: jest.fn().mockResolvedValue(clientStub()),
  deleteClient: jest.fn().mockResolvedValue(clientStub()),
})


但是我需要命名它以匹配自动导入,所以将clientService重命名为PrivateClientService
并且测试通过了进口:)

相关问题