Error When testing angular component with abp backend

Error When testing angular component with abp backend

Problem Description:

`TypeError: Cannot read properties of undefined (reading 'Default')
TypeError: Cannot read properties of undefined (reading 'Default')
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@abp/ng.core/fesm2015/abp-ng.core.js:258:45
    at EnvironmentService.getApiUrl (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@abp/ng.core/fesm2015/abp-ng.core.js:273:16)
    at MockRestService.getApiFromStore (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@abp/ng.core/fesm2015/abp-ng.core.js:323:33)
    at MockRestService.request (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@abp/ng.core/fesm2015/abp-ng.core.js:331:27)
    at AppService.getWorkspaceDictionary (http://localhost:9876/_karma_webpack_/webpack:/src/app/proxy/apps/app.service.ts:76:22)
    at new DictionaryServiceService (http://localhost:9876/_karma_webpack_/webpack:/src/app/new-dataflow/services/dictionary-service/dictionary-service.service.ts:14:21)
    at Object.DictionaryServiceService_Factory [as factory] (ng:///DictionaryServiceService/ɵfac.js:4:10)
    at R3Injector.hydrate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11457:1)
    at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11276:1)
    at NgModuleRef$1.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:25352:1)`

It should work properly but for some reason, it doesn’t work.

Here is my spec file with all dependencies used inside it.

import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms'
import {
  ConditionalGateNodeConfigurations,
  conditionModeOptions,
} from '@proxy/data-flows/flow-structure/flow-control-nodes';
import { DictionaryServiceService } from '../../services/dictionary-service/dictionary-service.service';

@Component({
  selector: 'app-conditional-gate-node',
  templateUrl: './conditional-gate-node.component.html',
  styleUrls: ['./conditional-gate-node.component.scss'],
})
export class ConditionalGateNodeComponent implements OnInit {
  @Input() form: FormGroup;
  @Input() inputHeaders: any[] = [];

  workspaceDic: Record<string, string> = {};

  modeOptionsDic: any[] = [];

  conditionModeOptions = conditionModeOptions;

  constructor(private dictionaryService: DictionaryServiceService) {}

  ngOnInit(): void {
    this.dictionaryService.workspaceDic$.subscribe(res => {
      this.workspaceDic = res;
    });
    this.dictionaryService.getDic();

    this.conditionModeOptions.forEach(option => {
      this.modeOptionsDic.push({
        key: option.key.replace(/([a-z])([A-Z])/g, `$1 $2`),
        value: option.value,
      });
    });
  }
}

Just did it as per documentation instructions but still facing this error.

It works in other components in the same module which is confusing.

Solution – 1

You should have kept your test code but I will offer you some tips.

The issue arises because you’re providing the actual DictionaryService and this service relies on a bunch of other things and there is something wrong with what it is relying on. Usually, I mock all external dependencies when I am testing.

Check the following out:

describe('ConditionalGateNodeComponent', () => {
  let fixture: ComponentFixture<ConditionalGateNodeComponent>;
  let component: ConditionalGateNodeComponent;
  // !! Declare a mock
  let mockDictionaryService: jasmine.SpyObj<DictionaryService>;
  
  beforeEach(waitForAsync(() => {
    // !! Create a spy object where the first string argument is optional 
       // and for debugging purposes.
       // The second array of string argument are the public methods you would like to mock
       // The third object argument are instance variables you would like to mock.
   mockDictionaryService = jasmine.createSpyObj<DictionaryService>('DictionaryService', ['getDic'], { workspaceDic$: of({ hello: 'goodbye' }) });

    TestBed.configureTestingModule({
      declarations: [ConditionalGateNodeComponent],
      providers: [
        // !! Provide the fake for the real dependency
        { provide: DictionaryService, useValue: mockDictionaryService },
      ],
      // !! Below says that if you see any components you don't know how to paint/render, treat them as dead HTML.
      schemas: [NO_ERRORS_SCHEMA]
    });
  }));
  
  beforeEach(() => {
    fixture = TestBed.createComponent(ConditionalGateNodeComponent);
    component = fixture.componentInstance;
    // !! The first fixture.detectChanges() is when ngOnInit is called
    fixture.detectChanges();
  });
});

The rest of the tests should be the same more or less. This is a great resource: https://testing-angular.com/testing-components-depending-on-services/#testing-components-depending-on-services and I have linked to you the chapter on testing components depending on services.

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject