简体   繁体   中英

Testing Angular Directive with async call in onInit

I have an Angular Directive, which makes call for authorization service in it's onInit method. It looks like that:

@Directive({
  selector: '[checkRights]'
})
export class RightsDirective implements OnInit{

  @Input('checkRights') expectedRights: Right[];

  constructor(private _element: ElementRef, private _userService: UserService) {
  }

  ngOnInit() {
    this._userService.hasAnyRights(this.expectedRights).subscribe(hasRights => {
      if(hasRights){
        this._element.nativeElement.remove();
      }
    })
  }
}

I want to test it, so I created a test, which sets it up in dummy Component:

describe('RightsDirective', () => {

  let component: TestRightsDirectiveComponent;
  let fixture: ComponentFixture<TestRightsDirectiveComponent>;
  let userService: UserService;
  let parentElement: DebugElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TestRightsDirectiveComponent, RightsDirective],
      providers: [UserService],
      imports: [HttpClientTestingModule]
    });
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TestRightsDirectiveComponent);
    component = fixture.componentInstance;
    parentElement = fixture.debugElement.query(By.css('div'));
    userService = TestBed.get(UserService);
  });

  it('should remove elements when user has no rights to it', async(() => {
    spyOn(userService, 'hasAnyRights').and.returnValue(of(false));

    expect(parentElement.children.length).toEqual(0);
  }));

});

@Component({
  template: `<div> <span [checkRights]="['ADMIN']"> </span></div>`
})
class TestRightsDirectiveComponent {
}

Now, i know it won't work. I am aware there are multiple problems with test itself, it is just an example of what i want to check.

I tried multiple times with detectChanges, fakeAsync and tick()s etc. I spent last 3 hours on it (it is my first time testing directive and i'm pretty new to Angular itself) and checked first 4 pages of google.

How can i ensure, that: - response from service is mocked before onInit kicks in? - .subscribe() in directive is completed before expect in test? Are there any other issues I am not seeing? Is config correct?

As far as your unit test file is concerned, ngOnInit will not run until you explicitily command it to. The lifecycle hooks don't work automatically in test files as they do in normal component loading.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM