在Nest JS单元测试中,使用实型方法代替SpyOn方法

时间:2018-08-14 13:23:10

标签: node.js unit-testing jasmine nestjs

我正在使用Jasmin在框架NestJS中实现单元测试。我在测试我的一项服务时遇到了问题。经过长时间的调试,我不知道我的代码有什么问题。看来我的服务没有使用间谍功能,而是使用了真实的方法。

我正在使用以下版本的软件包:

package.json

"jasmine": "3.1.0"
"@nestjs/testing": "4.6.6"
"@nestjs/common": "4.6.6"
"typescript": "2.6.2"
"node": "8.8.1"

在测试一种方法- prepareOrderDataOnCreate 时遇到问题。 在此方法中,我从其他服务调用了2个方法。

order.service.ts

@Component()
export class OrdersServiceComponent {
  constructor(
    private userService: UsersServiceComponent,
    private orderStatusService: OrderStatusServiceComponent,
    ...) {}

  async prepareOrderDataOnCreate(user): Promise<Order> {
    const status = await this.orderStatusService.getStatus();
    const user = await this.userService.getOne(user.id);

    return {
      ...
    };
  }
}

我模拟了这两种服务,并为这两种方法创建了SpyOn,以检查它们是否 toHaveBeenCalled 。但是当我运行测试时出现错误:

  

错误::可能是间谍,但得到了功能。

调试后,我发现单元测试不是从SpyOn而是从模拟文件中使用 usersService.getOne (请参见 user.service。)。模拟。ts ),尽管事实是从SpyOn使用了 orderStatusService.getStatus

order.service.spec.ts

describe('OrdersServiceComponent', () => {
  let ordersService: OrdersServiceComponent;
  let usersService: UsersServiceMock;

  beforeEach(async() => {
    const module = await Test.createTestingModule({
      controllers: [OrdersController],
      components: [
        OrdersServiceComponent,
        {provide: UsersServiceComponent, useClass: UsersServiceMock},
        {provide: OrderStatusServiceComponent, useClass: OrderStatusServiceMock},
        ...
      ]
    }).compile();

    ordersService = module.get<OrdersServiceComponent>(OrdersServiceComponent);
    orderStatusService = module.get<OrderStatusServiceMock>(OrderStatusServiceComponent as any);
    usersService = module.get<UsersServiceMock>(UsersServiceComponent as any);
  });

  it('prepareOrderDataOnCreate method returns order on success', () => {
    spyOn(orderStatusService, 'getStatus').and.stub();
    spyOn(usersService, 'getOne').and.callFake(() => console.log('SPY'));

    ordersService.prepareOrderDataOnCreate({...}).then(res => {
      expect(usersService.getOne).toHaveBeenCalled();
      expect(orderStatusService.getStatus).toHaveBeenCalled();
    });
  });
});

使用以下模拟方法代替间谍单元测试:

user.service.mock.ts

@Component()
export class UsersServiceMock {
  async getOne(): Promise<any> {
    return Promise.resolve({});
  }
}

这真的很奇怪,因为如果我在 prepareOrderDataOnCreate()之前在此单元测试中调用 usersService.getOne() 我从callFake获得console.log。

更新

我发现,当我运行测试并调用服务方法 prepareOrderDataOnCreate 时,首先是 userService.getOne >是间谍功能,并且在方法 userService.getOne 中的任何代码更改为实函数之后。

async prepareOrderDataOnCreate(user): Promise<Order> {
    /*  this.userService.getOne is SPY FUNCTION */

    const status = await this.orderStatusService.getStatus();

    /*  this.userService.getOne is REAL MOCK FUNCTION */

    const user = await this.userService.getOne(user.id);

    ...
  }

0 个答案:

没有答案