我正在使用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);
...
}