0

I have the following spec test:

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { BASE_API_URL } from 'src/app/tokens/baseApiUrl.token';
import { RbacPermissionsService } from '../services/rbac-permissions.service';
import { SharedModule } from '../shared.module';

@Component({
  selector: 'app-mock-test',
  template: `<div *appHasPermission="{ items: 'view' }"></div>`,
  providers: []
})
export class MockTestComponent {
  constructor() {}
}

describe('HasPermissionDirective', () => {
  let mockTestComponent: MockTestComponent;
  let mockTestFixture: ComponentFixture<MockTestComponent>;
  let rbacPermissionsService: RbacPermissionsService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [MockTestComponent],
      imports: [SharedModule, HttpClientTestingModule],
      providers: [{provide: BASE_API_URL, useValue: '/some_api/'}]
    });

    rbacPermissionsService = TestBed.get(RbacPermissionsService);
    mockTestFixture = TestBed.createComponent(MockTestComponent);
    mockTestComponent = mockTestFixture.componentInstance;
  });

  it('should have no divs when permission is false', done => {
    spyOn(rbacPermissionsService, 'getPermission').and.returnValue(of(false));
    mockTestFixture.whenStable().then(() => {
      mockTestFixture.detectChanges();
      const divs = mockTestFixture.nativeElement.getElementsByTagName('div');
      expect(divs.length).toBeFalsy();
      done();
    });
  });

  it('should have a visible view element when permission is true', done => {
    spyOn(rbacPermissionsService, 'getPermission').and.returnValue(of(true));
    mockTestFixture.whenStable().then(() => {
      mockTestFixture.detectChanges();
      const divs = mockTestFixture.nativeElement.getElementsByTagName('div');
      expect(divs.length).toBeTruthy();
      done();
    });
  });
});

When I run this in conjunction with all other tests, it fails with the error:

NullInjectorError: StaticInjectorError(DynamicTestModule)[InjectionToken ]: 
  StaticInjectorError(Platform: core)[InjectionToken ]: 
    NullInjectorError: No provider for InjectionToken !

But when I run it with fdescribe the tests pass.

I wholeheartedly admit that spec tests are not my strong suit. My gut says their might be a timing issue since the tests work in isolation but not when run as part of the larger group of tests.

Thomas Preston
  • 697
  • 1
  • 7
  • 19
  • Do you have `constructor(@Inject(BASE_API_URL) public baseApiUrl)` in your directive? I think that can be the culprit but I am not sure how to fix it. Can you try putting an `xdescribe` on this test and see if the other tests all pass? If so, then most likely one of the other tests is changing this `InjectionToken`. I think for later versions of `Jasmine`, the order of the tests are ran in a random order to prevent them from relying on each other. See if you can change the order and see if that has any effect. – AliF50 Jul 15 '21 at 17:13
  • https://sqa.stackexchange.com/questions/36601/can-jasmine-tests-be-executed-in-a-specific-order <--- How to specify order. – AliF50 Jul 15 '21 at 17:14

0 Answers0