3

I have a component that uses an external js library: leader-line. When I try to test that component, it always throws an error that function for the external library is not defined.

component file

declare var LeaderLine: any;

@Component({
  selector: 'app-flow-line',
  templateUrl: './flow-line.component.html',
  styleUrls: ['./flow-line.component.css']
})
export class FlowLineComponent implements AfterViewInit, OnDestroy {

  @Input() public flowPathConfig: any = new Array();
  public myLines: any = new Array();
  public ngAfterViewInit() {
    for (let config of this.flowPathConfig) {
      if (document.getElementById(config.fromStep) && document.getElementById(config.toStep)) {
        this.myLines.push(new LeaderLine(
          document.getElementById(config.fromStep),
          document.getElementById(config.toStep)
        ));
      }
    }
  }

spec file

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FlowLineComponent } from './flow-line.component';
import { FundamentalNgxModule } from 'fundamental-ngx';


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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [FlowLineComponent],
      imports: [FundamentalNgxModule]
    })
      .compileComponents();
  }));

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

  it('it should draw line with pathConfig', () => {
    component.flowPathConfig = [{ fromStep: '1', toStep: '2' }];
    let el1 = document.createElement('div');
    el1.setAttribute('id', '1');
    let el2 = document.createElement('div');
    el2.setAttribute('id', '2');
    document.body.appendChild(el1);
    document.body.appendChild(el2);
    fixture.detectChanges();
    component.ngAfterViewInit();
    expect(component.myLines.length).toEqual(0);
    expect(component).toBeTruthy();
  });
});

Following is the error trace. That shows reference error. PS: I have included the leader-line library using the following post: Use external javaScript library in angular application

HeadlessChrome 75.0.3770 (Mac OS X 10.14.6) FlowLineComponent it should draw line with pathConfig FAILED
        ReferenceError: LeaderLine is not defined
            at <Jasmine>
            at FlowLineComponent.LeaderLine [as ngAfterViewInit] (http://localhost:9876/_karma_webpack_/webpack:/src/app/flow/flow-line/flow-line.component.ts:34:43)
            at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/flow/flow-line/flow-line.component.spec.ts:45:15)
            at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:391:1)
            at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:308:1)
            at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:390:1)
            at Zone../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:150:1)
            at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:561:1)
            at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:576:1)
            at <Jasmine>
HeadlessChrome 75.0.3770 (Mac OS X 10.14.6): Executed 13 of 16 (1 FAILED) (0 secs / 3.274 secs)
HeadlessChrome 75.0.3770 (Mac OS X 10.14.6) FlowLineComponent it should draw line with pathConfig FAILED
        ReferenceError: LeaderLine is not defined
            at <Jasmine>
            at FlowLineComponent.LeaderLine [as ngAfterViewInit] (http://localhost:9876/_karma_webpack_/webpack:/src/app/flow/flow-line/flow-line.component.ts:34:43)
            at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/flow/flow-line/flow-line.component.spec.ts:45:15)
            at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:391:1)
            at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:308:1)
            at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:390:1)
            at Zone../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:150:1)
            at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:561:1)
            at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:576:1)

2 Answers 2

2

I would try to import the lib like this :

import * as LeaderLine from 'leader-line';

instead of the var declaration. Is it only the tests that doesn't work or when you run your app it throws the error as well ?

Sign up to request clarification or add additional context in comments.

1 Comment

I have added external js into angular.json it works fine in runtime. I throw an error in a test only. If I do import statement in spec file as you mentioned, it throws EsLint error because I do not call LeaderLine explicitly in a test.
1

I inject the methods in the component by using the function declaration way.

declare function A();

A way to test only the component's methods, and ignore all the imported ones from the external js file. You can create a mock/<external.js> file, that will replace the origin on testing mode. You have to add it also into the angular.json file in test configuration.

"test": {
      "builder": "@angular-devkit/build-angular:karma",
      "options": {
        "main": "src/test.ts",
        "polyfills": "src/polyfills.ts",
        "tsConfig": "src/tsconfig.spec.json",
        "karmaConfig": "src/karma.conf.js",
        "sourceMap": true,
        "assets": [
          "src/favicon.ico",
          "src/assets",
          "src/env.js"
        ],
        "styles": [
          "src/styles.css",
          "src/sass/intracom-light.scss"
        ],
        "scripts": [
          "src/assets/mock/js/maps.js"
        ]
      }
    },

Replace the body of the calling methods to set up the testing behavior.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.