Home > other >  Error When testing angular component with abp backend
Error When testing angular component with abp backend

Time:12-09

`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.

CodePudding user response:

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.

  • Related