masterach masterach - 25 days ago 6
Javascript Question

Why do I exactly need detectChanges in angular2?

I have the following code:

it ("test detect change", async()=>{
let fixture= TestBed.createComponent(AppComponent);
let element1= fixture.debugElement.nativeElement.querySelector("h1");
expect(element1.textContent).toContain("come");
element1.textContent="new";
//fixture.detectChanges();
expect(element1.textContent).toContain("come");
});


Regardless of fixture.detectChanges() the element1.textContent() changes to the value of "new"? Shouldn't the change happen only if I call the detectChanges() function?. Otherwise, what is the point of having detectChanges anyway since the change is registered without the function being called?

Basically I expect my last expect function to pass the test since the changes shouldn't have had been registered with the element1.textContent="new" because of not calling the detectChanges function

Answer Source

You're not testing your component correctly. You're not suppose to change the fixture's contents. You want to change the components properties and check if the fixture has changed accordingly, and for this you will need the detectChanges() method.

Example:

app.component.ts

@Component({
  selector   : 'app-root',
  template: '<h1>{{ title }}</h1>',
})
export class AppComponent {
  title = 'Test';
}

app.component.spec.ts

it('should change the title', () => {
  const compiled = fixture.debugElement.nativeElement;
  const component = fixture.componentInstance;

  expect(compiled.querySelector('h1').textContent).toBe('Test');
  component.title = 'New';
  fixture.detectChanges(); // <- Required for the following expectation to pass
  expect(compiled.querySelector('h1').textContent).toBe('New');
});

To answer your question directly you need the fixtures detectChanges() method in order to detect changes that happened inside the component and re-render the fixture.