Dickens A S
Dickens A S

Reputation: 4054

Angular 11 Testing component rendered outside router outlet

Below is a typical code which displays error message common to all component

<div>
   <div>
     <app-alert></app-alert>
   </div>
   <div>
     <router-outlet></router-outlet>
   </div>
</div>

When there is component has an error, the message is going to display inside the <app-alert> tag

But the component rendered using TestBed will not render that tag

The <app-alert> tag is served using AlertComponent class and AlertService class

The AlertService is injected as private via constructor

@Component({ templateUrl: 'login.component.html' })
export class LoginComponent {
    constructor(private alertService: AlertService) { }
}

In reference to Angular Testing Basics fixture.debugElement will not give the <app-alert> tag the reason being the tag is outside the router-outlet

How will I test login failure and display of message invalid credentials within login.component.spec.ts

Upvotes: 0

Views: 380

Answers (1)

AliF50
AliF50

Reputation: 18809

You can create a TestHost component that houses both of them in in your .spec.ts file.

@Component({
  template: `
     <app-alert></app-alert>
     <login></login>
  `
})
class TestHostComponent {
}
.....
TestBed.configureTestingModule({ 
      declarations: [AppAlertComponent, LoginComponent, TestHostComponent],
      providers: [/* your providers */] 
})

fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
// get a handle on the login component/class
loginComponent = fixture.debugElement.query(By.directive(LoginComponent)).componentInstance;
// get a handle on the app alert component/class
alertComponent = fixture.debugElement.query(By.directive(AppAlertComponent)).componentInstance;

With that setup both login and app-alert will be painted and you can test how they work together.

I think I explained a bit more than this link but it should help as well.

Upvotes: 1

Related Questions