0

I have a hybrid Angular project. But I have problems with unit testing.

I have tried this solution but it seems doesn't work for my project.

there is an error from ng test command.

Chrome 111.0.0.0 (Windows 10) GoComponent should create FAILED
        NullInjectorError: R3InjectorError(DynamicTestModule)[ABCadminService -> ApiconfigurationService -> ng1ServiceProviderUpgrade -> ng1ServiceProviderUpgrade]:
          NullInjectorError: No provider for ng1ServiceProviderUpgrade!
        error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'ABCadminService', 'ApiconfigurationService', 'ng1ServiceProviderUpgrade', 'ng1ServiceProviderUpgrade' ] })
        NullInjectorError: R3InjectorError(DynamicTestModule)[ABCadminService -> ApiconfigurationService -> ng1ServiceProviderUpgrade -> ng1ServiceProviderUpgrade]:
          NullInjectorError: No provider for ng1ServiceProviderUpgrade!
            at NullInjector.get (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11100:27)

component.spec.ts

describe('GoComponent', () => {
  let component: GoComponent;
  let fixture: ComponentFixture<GoComponent>;
  let mockABCadminService;

  beforeEach(async () => {
    mockABCadminService = jasmine.createSpyObj(['getABC']);
    mockABCadminService.getABC.and.returnValue('abc');
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
      declarations: [GoComponent],
      providers: [
        { provide: ABCadminService, useValue: mockABCadminService }
      ]
    })
      .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(GoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

service.ts

@Injectable({
    providedIn: 'root'
})

export class ABCadminService {
    private apiURL: string;
    private baseUrl: string = '/abcadmin';
    private url: string;
    constructor(
        private http: HttpClient,
        private apiConfig: ApiconfigurationService
    ) {
        this.apiURL = this.apiConfig.getApiUrl();
        this.url = this.apiURL + this.baseUrl;
    }

    getABC(): Observable<abcTree> {
        return this.http.get<abcTree>(this.url);
    }
}

component.ts

export class GoComponent implements OnInit {

  contentLoading: boolean = false;
  content: string = '';

  constructor(private abcadminService: ABCadminService) { }

  ngOnInit(): void {
      this.contentLoading = true;
      this.abcadminService.getABC().subscribe(data => {
          this.content = data;
          this.contentLoading = false;
    })
  }
}

I think if I can mock ABCadminService I don't have to ng1ServiceProviderUpgrade anymore.
Or should I mock every layer of [ABCadminService -> ApiconfigurationService -> ng1ServiceProviderUpgrade -> ng1ServiceProviderUpgrade]

Sunny
  • 167
  • 1
  • 3
  • 13

1 Answers1

1

It seems that somehow, your mocking is not working with the providers array. Try the following:

// !! Add await here so we wait for compileComponents
await TestBed.configureTestingModule({
      // !! Remove this imports, it shouldn't be needed. Your component does not need it
      // imports: [HttpClientModule],
      declarations: [GoComponent],
      // !! The issue occurs here, somehow the mock is not being provided to the compoennts
      providers: [
        { provide: ABCadminService, useValue: mockABCadminService }
      ]
    })
      .compileComponents();

The last comment is what needs to be addressed. When we are mocking the ABCadminService, the real one should not be needed. Put a console.log/debugger in the constructor of the service and make sure it is not called. If it is called, understand why it is being called.

It seems you're mocking correctly, I am not sure why the real ABCadminService is being used.

AliF50
  • 16,947
  • 1
  • 21
  • 37
  • Thank you so much. I found that if we use Hybrid Angular which are the component use service from Angularjs, it would be hard to test. Right now, I'm trying to solve this problem by answer https://stackoverflow.com/a/54657035/9934300. I found a lot of problems when I use Hybrid Angular project. These problems won't be found in regular Angular projects. – Sunny Mar 13 '23 at 15:47
  • Ok, I see. I have never dealt with a hybrid project, good luck. – AliF50 Mar 13 '23 at 20:10