NetsJs控制器单元测试返回TypeError:无法读取未定义的属性

时间:2020-05-12 12:24:19

标签: unit-testing jestjs nestjs typeorm nestjs-config

尝试在NetsJs Controller上编写单元测试,但得到返回TypeError:无法读取未定义的属性'getGroup'

groups.controller.spec.ts

describe("GroupsController", () => {
    let groupsController: GroupsController;
    let groupsService: GroupService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            controllers: [GroupsController],
            providers: [
                {
                    provide: getRepositoryToken(Groups),
                    useFactory: GroupModelMockFactory
                },
                {
                    provide: getRepositoryToken(Roles),
                    useFactory: roleModelMockFactory
                },
                RSTLogger,
                RolesService,
                GroupService,
                CommonService,
                DatabaseService,
                GroupsController
            ]
        }).compile();

        groupsService = module.get<GroupService>(GroupService);
        groupsController = module.get<GroupsController>(GroupsController);
    });


    it("should be defined", () => {
        expect(groupsController).toBeDefined();
    });

    describe("Find Group", () => {
        it("Get group", async () => {
            try {
                const expectedResult = {
                    groupName: "group123",
                    description: "Group Description",
                    roleId: 1
                };
                 expect(
                    await groupsController.getGroup(1, 'no')
                 ).toEqual({ data: expectedResult });
            } catch (e) {
                console.log(e);
            }
        });
    });
});

unitTestingMocks.ts

export const roleModelMockFactory = () => ({
    findOne: id => ({
      id: "1",
      name: "Name",
      description: "Description",
      resource: []
    }),
    create: RoleDto => ({
      name: "Role1",
      description: "Role Description",
      resource: []
    }),
    save: RoleDto => ({
      name: "Role1",
      description: "Role Description",
      resource: []
    }),
    update: RoleDto => ({
      exec: async () => ({
        name: "Updated Role",
        description: "Role Description",
        resource: []
      })
    }),
    findByIdAndRemove: id => ({
      exec: async () => ({
        name: "Deleted Role",
        description: "Description",
        resource: []
      })
    }),
  });

  export const GroupModelMockFactory = () => ({

    findByRoleId: id => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    findOne: dto => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    create: groupDto => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    save: groupDto => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    findOneOrFail: id => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    update: groupDto => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    delete: id => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    }),
    getGroup: id => ({
      groupName: "group123",
      description: "Group Description",
      roleId: 1
    })
  });

groups.controller.ts

@ApiTags('groups')
@ApiBearerAuth()
@Controller('groups')
@Injectable({ scope: Scope.REQUEST })
export class GroupsController {
    constructor(private readonly groupsService: GroupService,
        private rstLogger: RSTLogger,
        private commonService: CommonService,
        @Inject(REQUEST) private readonly request: Request) {
        this.rstLogger.setContext('GroupController');
    }

    @Get(':groupId')
    @ApiQuery({ name: 'groupId' })
    @ApiQuery({ name: 'relatinalData' , enum: ['yes', 'no']})
    @UseGuards(JWTTokenAuthGuard, RolesGuard)
    async gerGroup(@Query('groupId') groupId, @Query('relatinalData') relatinalFlag) {
        const group = await this.groupsService.getGroup(groupId, relatinalFlag);
        if (!group) throw new NotFoundException('Group does not exist!');
        return { data: group };
    }

}

group.service.ts

export class GroupService {
    constructor(
        @InjectRepository(Groups) private readonly groupModel: Repository<Groups>,
        private rstLogger: RSTLogger,
        private readonly databaseService: DatabaseService,
        private readonly rolesService: RolesService) {
        this.rstLogger.setContext('GroupServices');
    }

    async getGroup(ID, relatinalFlag = 'no'): Promise<Groups> {
        if (relatinalFlag && relatinalData.yes === relatinalFlag) {
            return await this.databaseService.findOneWithRelation(this.groupModel, { id: ID }, { relations: ['role'] });
        } else {
            return await this.databaseService.findOne(this.groupModel, { id: ID });
        }
    }
}

尝试从控制器获取组时遇到错误

  TypeError: Cannot read property 'getGroup' of undefined

任何人都可以指导我这里需要正确的内容。

1 个答案:

答案 0 :(得分:1)

似乎GroupService的依存关系有其自己的依存关系。如果它们对这次测试不重要,您可以像这样模拟它们

 {provide: RSTLogger, useValue: jest.fn() },

但是我看到DatabaseService有它自己的依赖关系,应该正确地提供或嘲笑它。