Angular Dependency Injection删除动态添加的属性

时间:2019-02-28 07:09:46

标签: angular typescript jasmine

我正在尝试为茉莉花创建一个函数,该函数监视一个完整的对象,包括方法,设置器和获取器。工厂看起来像这样:

// @dynamic
export class SpyFactoryService {
  public static createSpy<T>(spiedClass: Type<T>): SpyOf<T> {
    const functionNames = this.getFunctionNames(spiedClass).map(f => f.propertyName);

    // Add the functions
    const result = jasmine.createSpyObj('spy', [...functionNames]);

    // Add "empty" setters per setter-property of the spied Class
    this.getSetters(spiedClass)
      .map(prop => {
        Object.defineProperty(result, prop.propertyName, {
          set: function () {
          }
        });
      });

    // Add getters, which return undefined, for each getter-property of the spied Class
    this.getGetters(spiedClass)
      .map(prop => {
        Object.defineProperty(result, prop.propertyName, {
          get: function () {
            return undefined;
          }
        });
      });

    return result;
  }

  private static getFunctionNames<T>(spiedClass: Type<T>): ObjectProperty[] {
    return this.getObjects(spiedClass).filter(prop => prop.propertyDescriptor.value instanceof Function);
  }

  private static getGetters<T>(spiedClass: Type<T>): ObjectProperty[] {
    return this.getObjects(spiedClass).filter(prop => prop.propertyDescriptor.get);
  }

  private static getObjects<T>(spiedClass: Type<T>): ObjectProperty[] {
    const prototype = spiedClass.prototype;
    const result = Object.getOwnPropertyNames(prototype)
      .filter(name => !!Object.getOwnPropertyDescriptor(prototype, name))
      .map(name => new ObjectProperty(name, Object.getOwnPropertyDescriptor(prototype, name)!));

    return result;
  }

  private static getSetters<T>(spiedClass: Type<T>): ObjectProperty[] {
    return this.getObjects(spiedClass).filter(prop => prop.propertyDescriptor.set);
  }
}

代码不是很漂亮,但是它为每个函数以及“空”属性返回了一组间谍,让我以后可以监视它们,例如:

const stateServiceMock = SpyFactoryService.createSpy(ConstructionDefectPicturesStateService);
spyOnProperty(stateServiceMock, 'pictures$', 'get').and.returnValue(new BehaviorSubject<ConstructionDefectPictureDto[]>([]));

不幸的是,有一件奇怪的事:假设我使用名为$ pictures的属性设置了一个测试,如下所示:

 beforeEach(async(() => {
    const stateServiceMock = SpyFactoryService.createSpy(ConstructionDefectPicturesStateService);
    spyOnProperty(stateServiceMock, 'pictures$', 'get').and.returnValue(new BehaviorSubject<ConstructionDefectPictureDto[]>([]));

    TestBed.configureTestingModule({
      declarations: [ConstructionDefectPicturesComponent],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        {
          provide: ConstructionDefectPicturesStateService,
          useValue: stateServiceMock
        }
      ]
    })
      .compileComponents();

在组件本身中,我看到picture $是未定义的。但是调试调试后,在提供实例时,我看到它已定义。另外,在提供之前做类似的事情:

const val = (<any>stateServiceMock).pictures$;
(<any>stateServiceMock).pictures2 = val;

实际上是否将一个名为pictures2的属性传递给Component,而不是pictures $: enter image description here

Angular对useValue提供的对象有什么用,可以解释为什么我“失去了”属性,尽管可以确定设置了这些属性?

0 个答案:

没有答案