首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >隔离控制器单元测试/ NestJS / JestJS /类型记录中的问题

隔离控制器单元测试/ NestJS / JestJS /类型记录中的问题
EN

Stack Overflow用户
提问于 2021-07-10 19:27:43
回答 1查看 872关注 0票数 0

我想用模拟服务为我的http控制器编写单元测试。其主要思想是模拟服务并为其提供一些模拟实现。

下面是我完成此操作的设置(我将跳过一些imports语句,并在我们的上下文装饰器中无用,以减少代码行数):

create-user.http.controller.ts:

代码语言:javascript
复制
export class CreateUserHttpController {
  constructor(
    @Inject(createUserSymbol)
    private readonly createUser: CreateUserService,
  ) {}

  @Post(appRoutes.users.root)
  async create(@Body() body: CreateUserRequest): Promise<IdResponse> {
    const command = new CreateUserCommand({
      email: body.email,
      name: body.name,
      password: body.password,
      role: 'user',
    });

    const id = await this.createUser.createUser(command);

    return new IdResponse(id.value);
  }
}

create-user.http.controller.spec.ts:

代码语言:javascript
复制
import { Test } from '@nestjs/testing';

import { ID } from 'src/core/value-objects/id.value-object';

import { createUserSymbol } from '../../user.providers';
import { CreateUserHttpController } from './create-user.http.controller';
import { CreateUserService } from './create-user.service';

jest.mock('./create-user.service', () => {
  return {
    CreateUserService: jest.fn().mockImplementation(() => {
      return {
        createUser: () => {
          console.log('ts');
        },
      };
    }),
  };
});

describe('CreateUserHttpController', () => {
  let createUserHttpController: CreateUserHttpController;
  let createUserService: CreateUserService;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CreateUserHttpController],
      providers: [
        {
          provide: createUserSymbol,
          useValue: CreateUserService,
        },
      ],
    }).compile();

    createUserHttpController = await moduleRef.resolve(
      CreateUserHttpController,
    );
    createUserService = await moduleRef.resolve(createUserSymbol);
  });

  describe('create', () => {
    it('should call once createUser method in service', async () => {
      const expectedResult = new ID('test');

      jest
        .spyOn(createUserService, 'createUser')
        .mockResolvedValue(expectedResult);

      const result = await createUserHttpController.create({
        email: 'test@mail.ru',
        name: 'test',
        password: 'test',
      });

      expect(createUserService).toHaveBeenCalledTimes(1);
    });
  });
});

在这个设置中,我遇到了这样的问题:(不能监视属性,因为它不是函数;而是未定义的)

我尝试过console.log模拟服务实例,以检查是否存在“createUser”属性。看上去好像不在那里。

我已经很深入地检查了jest文档,尤其是这里- 用于模拟非默认类导出的jest doc。。我花了大约6个小时,尝试了所有可用的选择,但结果仍然是一样的。

我也查过这里的指南- 介质导轨。这个幸运的家伙似乎有相同的设置,没有任何问题。

因此,从我的角度来看,由于某种原因,jest.mock函数似乎没有使用createUser方法初始化模拟服务。

任何帮助都很感激!提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-11 17:55:48

我明白这是怎么回事了。在createUserSymbol的自定义提供程序中,您使用的是为CreateUserService创建的模拟,但是这个模拟是一个工厂,而不是一个直接值,所以您应该使用useFactory代替useValue,这样Nest就可以最终调用工厂函数。如果你移除jest.fn().mockImplementation(),只需看一下会有什么

代码语言:javascript
复制
{
  CreateUserService: () => {
    return {
      createUser: () => {
        console.log('ts');
      }
    }
  }
}

因此,要获得返回的对象,您需要首先调用函数,即CreateUserService(),或者,正如前面提到的,您可以使用useFactory,Nest将为您调用该方法。

另一个不同的选择是完全放弃jest.mock(),只需将一个自定义值传递给Nest以进行模拟,如

代码语言:javascript
复制
const moduleFixture = await Test.createTestingModule({
  controllers: [CreateUserController],
  providers: [
    {
      provide: createUserSymbol,
      useValue: {
        createUse: jest.fn().mockImplementation(() => console.log('ts'))
      }
    }
  ],
}).compile();

这种方法也可以测试模块不可知论,因此,如果出于任何原因决定更改库,则可以更容易地交换

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68330931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档