2017-01-02 3 views
5

Я только что начал с Unit-Testing, и я смог издеваться над своими услугами и некоторыми из угловых и ионных, но независимо от того, что я делаю ChangeDetectorRef, одна и та же.Угловой 2: Как издеваться над ChangeDetectorRef при модульном тестировании

Я имею в виду, какое колдовство это?

beforeEach(async(() => 
    TestBed.configureTestingModule({ 
     declarations: [MyComponent], 
     providers: [ 
     Form, DomController, ToastController, AlertController, 
     PopoverController, 

     {provide: Platform, useClass: PlatformMock}, 
     { 
      provide: NavParams, 
      useValue: new NavParams({data: new PageData().Data}) 
     }, 
     {provide: ChangeDetectorRef, useClass: ChangeDetectorRefMock} 

     ], 
     imports: [ 
     FormsModule, 
     ReactiveFormsModule, 
     IonicModule 
     ], 
    }) 
    .overrideComponent(MyComponent, { 
     set: { 
     providers: [ 
      {provide: ChangeDetectorRef, useClass: ChangeDetectorRefMock}, 
     ], 
     viewProviders: [ 
      {provide: ChangeDetectorRef, useClass: ChangeDetectorRefMock}, 
     ] 
     } 
    }) 
    .compileComponents() 
    .then(() => { 
     let fixture = TestBed.createComponent(MyComponent); 
     let cmp = fixture.debugElement.componentInstance; 

     let cdRef = fixture.debugElement.injector.get(ChangeDetectorRef); 

     console.log(cdRef); // logs ChangeDetectorRefMock 
     console.log(cmp.cdRef); // logs ChangeDetectorRef , why ?? 
    }) 
)); 

it('fails no matter what', async(() => { 
    spyOn(cdRef, 'markForCheck'); 
    spyOn(cmp.cdRef, 'markForCheck'); 

    cmp.ngOnInit(); 

    expect(cdRef.markForCheck).toHaveBeenCalled(); // fail, why ?? 
    expect(cmp.cdRef.markForCheck).toHaveBeenCalled(); // success 

    console.log(cdRef); // logs ChangeDetectorRefMock 
    console.log(cmp.cdRef); // logs ChangeDetectorRef , why ?? 
    })); 

@Component({ 
    ... 
}) 
export class MyComponent { 
constructor(private cdRef: ChangeDetectorRef){} 

ngOnInit() { 
    // do something 
    this.cdRef.markForCheck(); 
} 
} 

Я попробовал все, async, fakeAsync, injector([ChangeDetectorRef],() => {}).

Ничего не работает.

+0

Редактор ChangeDetectorRef получает специальную обработку компилятором Angular 2. Я думаю, вы не можете это предоставить. Вы можете проверить тест для AsyncPipe https://github.com/angular/angular/blob/8f5dd1f11e6ca1888fdbd3231c06d6df00aba5cc/modules/%40angular/common/test/pipes/async_pipe_spec.ts. Используется SpyChangeDetectorRef – yurzui

+0

. Я попадаю в ту же проблему - как люди работают вокруг этого? – SamF

ответ

6

В случае, если кто работает в этом, это один из способов, который работал хорошо для меня:

Как вы инъекционный экземпляр ChangeDetectorRef в конструкторе:

constructor(private cdRef: ChangeDetectorRef) { } 

У вас есть что cdRef, как один частных атрибутов компонента, что означает, что вы можете следить за компонентом, заглушить этот атрибут и вернуть его, что хотите. Кроме того, вы можете утверждать свои вызовы и параметры по мере необходимости.

В вашем файле спецификаций вызовите свой тестовый элемент без предоставления ChangeDetectorRef, поскольку он не предоставит то, что вы ему даете. Установите компонент тот же beforeEach блок, поэтому он сбрасывается между спецификациями, как это делается в документации here:

component = fixture.componentInstance; 

Затем в тестах, шпионить непосредственно на атрибут

describe('someMethod()',() => { 
    it('calls detect changes',() => { 
    const spy = spyOn((component as any).cdRef, 'detectChanges'); 
    component.someMethod(); 

    expect(spy).toHaveBeenCalled(); 
    }); 
}); 

С шпиона вы можете использовать .and.returnValue() и вернуть его, что вам нужно.

Обратите внимание, что (component as any) используется как cdRef является частным атрибутом. Но private не существует в самом компилированном javascript, поэтому он доступен.

Это зависит от вас, если вы хотите получить доступ к приватным атрибутам во время выполнения таким образом для своих тестов. У меня лично нет проблем с этим, я делаю это по моим спецификациям, чтобы получить больше освещения.

Смежные вопросы