试图用 jest 测试我的巢 api,返回未定义

Posted

技术标签:

【中文标题】试图用 jest 测试我的巢 api,返回未定义【英文标题】:Trying to test my nest api with jest, returns undefined 【发布时间】:2019-09-21 19:27:53 【问题描述】:

我正在尝试使用 NestJs 框架创建一个 Jest 测试。

测试应该检查控制器和服务,但是 1) 控制器未定义和 2) 服务未定义。

这是我的 home-cards.controller.spec.ts 中的代码:

describe('HomeCardsController', () => 
    let homeCardsController: HomeCardsController;
    let homeCardsService: HomeCardsService;

    beforeEach(async () => 
        const module = await Test.createTestingModule(
            imports: [TypeOrmModule.forFeature([HomeCard])],
            controllers: [HomeCardsController],
            providers: [HomeCardsService]
        ).compile();

        homeCardsController = module.get<HomeCardsController>(HomeCardsController);
        homeCardsService = module.get<HomeCardsService>(HomeCardsService);
    );

    describe('findall', () => 
        it('should return an array of home cards', async () => 
            expect( await homeCardsController.findAll(1000)).toBeInstanceOf(Array);
        );
    );
);

错误:

作为控制器询问用户的新错误:

TypeError: Cannot read property 'clientId' of undefined

      17 |   async findAll(@Req() request): Promise<HomeCard[]> 
      18 |       const user: AuthUser = request.user;
    > 19 |       return await this.homeCardsService.findAll(user.clientId);
         |                                                       ^
      20 |   
      21 | 
      22 |   @Get(":id")

【问题讨论】:

【参考方案1】:

你必须模拟调用 HomeCardsController 的 HomeCardsService 方法

import  HomeCardService  from './home-cards.service.ts'; // your path to service
jest.mock('./home-cards.service.ts'); // your path to service

describe('HomeCardsController', () => 
    let homeCardsController: HomeCardsController;
    let homeCardsService: HomeCardsService;

    beforeEach(async () => 
        const module = await Test.createTestingModule(
            // imports: [TypeOrmModule.forFeature([HomeCard])], <- unit test don't need database, mock all
            controllers: [HomeCardsController],
            providers: [HomeCardsService]
        ).compile();

        homeCardsController = module.get<HomeCardsController>(HomeCardsController);
        homeCardsService = module.get<HomeCardsService>(HomeCardsService);
    );

    describe('findall', () => 
        it('should return an array of home cards', async () => 
            const result = []; // some result for mock method
            jest.spyOn(homeCardsService, 'findAll').mockImplementation(() => result);
            const request = user: clientId: 1000
            expect( await homeCardsController.findAll(request)).toBeInstanceOf(Array);
        );
    );
);

【讨论】:

您好,谢谢。我现在得到这个错误。我已经更新了问题 并且您不应该将导入添加到模块以进行单元测试 所以我已经添加了您的建议并且可行,但是开玩笑没有正确模拟控制器?我不知道。我再次在问题中添加了错误。控制器正在尝试获取具有客户端 ID 的用户对象,但由于我没有提出请求,所以它是未定义的。如何模拟这部分请求? 好的,我已经完成了 - 一切正常,谢谢。另外,玩笑测试是否会查询数据库?所以我的 find all 方法当前返回一个长度为 0 的数组,但它应该包含数据。我还必须嘲笑响应吗?如果是这样,如果我只是在嘲笑一切,那么测试的意义何在?只是为了测试业务逻辑?谢谢 是的,单元测试只是为了测试业务逻辑,但是你可以写e2e测试。 docs.nestjs.com/fundamentals/testing【参考方案2】:

在这种情况下:

expect( await homeCardsController.findAll(1000)).toBeInstanceOf(Array);

您输入了值 1000 而不是请求 @Req ,它应该是以下对象:

const request = 
  user: 
    clientId: 1000
  

expect( await homeCardsController.findAll(request)).toBeInstanceOf(Array);

如果您希望可以像这样模拟您的存储库(HomeCardsService 下面的大括号中的语法):

beforeEach(async () => 
  const module = await Test.createTestingModule(
    controllers: [HomeCardsController],
    providers: [
      HomeCardsService,
      
        provide: getRepositoryToken(HomeCard),
        useValue: jest.fn(() => (
        save: jest.fn().mockReturnThis(),
        createQueryBuilder: jest.fn(() => (
          select: jest.fn().mockReturnThis(),
          where: jest.fn().mockReturnThis(),
          getOne: jest.fn().mockReturnValueOnce(someMockedValue),
        )),
        ))(),
      ,
    ]
  ).compile();

【讨论】:

以上是关于试图用 jest 测试我的巢 api,返回未定义的主要内容,如果未能解决你的问题,请参考以下文章

用 jest 进行 Vue 测试:$route 始终未定义

Jest.fn-使用jest.mock时返回的值返回未定义

Jest.js强制窗口未定义。

使用grunt运行jest时未找到任何测试

由于错误无法读取未定义的模拟实现,无法使用 Jest 测试发布方法

如何在 JEST 单元测试中修复“SVG 未定义”