如何在Jest测试框架中创建模拟对象而不用担心对象的属性

时间:2019-09-02 08:34:28

标签: jestjs nestjs

我正在将NestJSJest框架一起测试NestJS Interceptor。我想为interceptors编写单元测试。拦截器功能要求两个参数。我已经创建了CallHandler的模拟对象,因为它只需要最少的一个必需参数。但是,我想创建一个ExecutionContext的间谍/模拟对象,该对象需要许多参数。如何实现?

拦截器看起来像:

@Injectable()
export class GetFlowDefinitionInterceptor implements NestInterceptor {
  public intercept(_context: ExecutionContext, next: CallHandler): Observable<FlowUI> {
    return next.handle().pipe(
      map(flow => {
        flow.name = 'new name'
        return flow;
      }),
    );
  }
}

测试看起来像

 it('interceptor test', () => {
    let _context: ExecutionContext = {}; <- that i want to mock, error below
    let next: CallHandler = {
      handle: function () {
        return of({});
      }
    }
    let result = new GetFlowDefinitionInterceptor().intercept(_context, next);
    expect(result.name).toEqual('new name');
  });

错误

let _context: ExecutionContext

Type '{}' is missing the following properties from type 'ExecutionContext': getClass, getHandler, getArgs, getArgByIndex, and 3 more.ts(2740)

2 个答案:

答案 0 :(得分:0)

绝对不是最好的选择,但是您可以编写let result = new GetFlowDefinitionInterceptor().intercept(_context as any, next);来忽略编译问题。 (as any非常重要)

答案 1 :(得分:0)

您可以测试逻辑而无需测试拦截器。

1):分离并测试逻辑:

export class FlowDefinitionMap {
  map(flow: FlowDefinition) {
    return {...flow, name: 'new name'};
  }
}

it('it should replace name', () => {
  const result = new FlowDefinitionMap().map({name: 'old name'});
  expect(result.name).toEqual('new name');
});

2)在拦截器中使用新的FlowDefinitionMap

@Injectable()
export class GetFlowDefinitionInterceptor implements NestInterceptor {
  public intercept(_context: ExecutionContext, next: CallHandler): Observable<FlowUI> {
    const flowDefinitionMap = new FlowDefinitionMap();

    return next.handle().pipe(
      map(flow => {
        return flowDefinitionMap.map(flow);
      }),
    );
  }
}