Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bypassing *ngIf on an Angular/Jasmine unit test

FYI Logged an issue on github and also included plunkr in the bug with details: https://github.com/angular/angular/issues/19292

I simply cannot get passed the ngIf in order to check the value. If I remove ngIf it works fine. To try and get around this I have hardcoded the value of ambassador directly in the beforeEach(). But to no avail I am missing something else.

In the HTML:

 <h3 class="welcome" *ngIf="ambassador"><i>{{ambassador.username}}</i></h3>

Jasmine:

beforeEach(() => {

    TestBed.configureTestingModule({
       declarations: [ ProfileComponent, BannedComponent ],
       providers:    [ HttpClient, {provide: AmbassadorService, useClass: MockAmbassadorService } ],
       imports:      [ RouterTestingModule, FormsModule, HttpClientModule ]
    });

    fixture = TestBed.createComponent(ProfileComponent);
    component    = fixture.componentInstance;

    // AmbassadorService actually injected into the component
    ambassadorService = fixture.debugElement.injector.get(AmbassadorService);
    componentUserService = ambassadorService;
    // AmbassadorService from the root injector
    ambassadorService = TestBed.get(AmbassadorService);

    // set route params
    component.route.params = Observable.of({ username: 'jrmcdona' });
    component.ambassador = new Ambassador('41', '41a', 'jrmcdona', 4586235, false);
    component.ngOnInit();
  });

  it('should search for an ambassador based off route param OnInit', () => {
     de = fixture.debugElement.query(By.css('.welcome'));
    el = de.nativeElement;
    fixture.detectChanges();
    const content = el.textContent;
    expect(content).toContain('jrmcdona', 'expected name');
  });
like image 679
Jordan McDonald Avatar asked Sep 22 '17 11:09

Jordan McDonald


People also ask

Can't bind to ngIf since it isn't a known property of Jasmine?

ERROR: 'Can't bind to 'ngIf' since it isn't a known property of 'p'. ' When there is that kind of error for the application itself, the fix is to ensure you add BrowserModule to the imports: [] in the @NgModule() of your application module ( app. module.

What does detectChanges do in Angular Jasmine tests?

detectChanges() tells Angular to run change-detection. Finally! Every time it is called, it updates data bindings like ng-if, and re-renders the component based on the updated data. Calling this function will cause ngOnInit to run only the first time it is called.

What is TestBed in Jasmine?

TestBed is a mock environment to run Angular2 component tests without the browser.


1 Answers

The problem is that DOM does not update until you manually detect changes, and you're attempting to query the DOM before your *ngIf renders (and ambassador value is detected).

  it('should search for an ambassador based off route param OnInit', () => {
    fixture.detectChanges();
     de = fixture.debugElement.query(By.css('.welcome'));
    el = de.nativeElement;
    const content = el.textContent;
    expect(content).toContain('jrmcdona', 'expected name');
  });

Moving the detectChanges() before the query() should solve the problem.

like image 139
Z. Bagley Avatar answered Sep 19 '22 07:09

Z. Bagley