NestJS如何在单元测试中创建新的猫鼬模型?

Posted

技术标签:

【中文标题】NestJS如何在单元测试中创建新的猫鼬模型?【英文标题】:NestJS how to create new mongoose Model in unittest? 【发布时间】:2019-10-10 10:05:30 【问题描述】:

我尝试对我的 NestJs Controller 类进行单元测试。我已经使用 ts-mockito 模拟了我的服务,但现在我很难创建我想要返回并期望由控制器返回的猫鼬对象。我如何设法创建新的模型对象进行测试?

这是我的服务:

@Injectable()
export class ProjectService 
    constructor(
        @InjectModel('Project') private readonly projectModel: Model<Project>,
        private tagService: TagService,
    )  ...

这是我的模特

let schema = new Schema(
    name: type: String, required: true,
    description: String,
    created: type: Date, default: Date.now,
);
export const ProjectSchema = schema;

export interface Project extends Document 
    readonly name: string,
    readonly description: string,
    readonly created: Date,

这是我的模块:

@Module(
    imports: [
        MongooseModule.forFeature([ name: 'Project', schema: ProjectSchema ]),
    ],
    controllers: [
        ProjectController
    ],
    providers: [
        ProjectService,
    ],
)
export class ProjectModule 

这是我的测试:

describe('ProjectController', async () => 
    let projectController: ProjectController;
    let projectServiceMock: ProjectService = mock(ProjectService);
    let projectModel: Model<Project>;

    beforeAll(async () => 
        projectModel = mock(Model);

        const module: TestingModule = await Test.createTestingModule(
            controllers: [ProjectController],
            providers: [
                
                    provide: ProjectService,
                    useValue: instance(projectServiceMock)
                ,
                
                    provide: 'Project',
                    useValue: instance(projectModel)
                
            ]
        ).compile();

        projectController = module.get<ProjectController>(ProjectController);
    );

现在我正在尝试创建一个新的项目对象并从我的服务中返回它并期望它来自控制器:

it('should return Project with id from projectService', async () => 
            const project = new projectModel(name: 'ProjectName', description: 'ProjectDescription');

            let result = Promise.resolve(project);
            when(projectServiceMock.getById('projectId')).thenReturn(result);

            await expect(projectController.getById('projectId')).toEqual(result);
        );

但我收到此错误:

Nest cannot find given element (it does not exist in current context)

      25 | 
      26 |         projectController = module.get<ProjectController>(ProjectController);
    > 27 |         projectModel = module.get<Model<Project>>('Project');
         |                               ^
      28 |     );
      29 | 
      30 |     describe('getAll', async () => 

我认为我可以从错误消息中读取到,将模型“获取”到测试肯定有问题,但我真的不知道如何在不启动连接的情况下获取模型...... 我能做些什么?你有一些适合你的示例代码吗?

【问题讨论】:

【参考方案1】:

使用@nestjs/mongoose中暴露的getModelToken函数:

import getModelToken from '@nestjs/mongoose';

    const module = await Test.createTestingModule(
      providers: [
        
          provide: getModelToken('ModelName'),
          useValue: ModelMock,
        ,
      ],
    ).compile()

modelMock = module.get<mongoose.Model<any>>('ModelNameModel'); // The getModelFunction just appends 'Model' to the Model name

【讨论】:

以上是关于NestJS如何在单元测试中创建新的猫鼬模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jest 来监视 Schema.virtual 的猫鼬?

使用 NestJS 测试猫鼬模型

如何对 NestJS 中的控制器应用警卫进行单元测试?

如何在 mocha 单元测试中使用猫鼬?

使用注入对 NestJS 控制器进行单元测试

如果文件未导出,如何使用在单独文件中定义的猫鼬模型?