bobbyrne01
bobbyrne01

Reputation: 6745

Error when testing a component which uses templateUrl

I can see in the test output that console.log(dummyComponentInstance); is being called and evaluating to undefined.

Also, console.log('beforeEach done'); is never logged.

dummy.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { DummyComponent } from './dummy.component';

describe('DummyComponent', () => {

  let dummyComponentInstance: DummyComponent;
  let fixture: ComponentFixture<DummyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [DummyComponent]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(DummyComponent);
        dummyComponentInstance = fixture.componentInstance;
        console.log('beforeEach done');
      });
  }));

  it('should work', () => {
    console.log(dummyComponentInstance);
    expect(dummyComponentInstance instanceof DummyComponent).toBe(true, 'should create DummyComponent');
  });
});

dummy.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'dummy',
  templateUrl: './dummy.component.html'
})
export class DummyComponent {
  public initialized = false;
}

Error after running the test:

07 06 2017 13:27:09.187:INFO [launcher]: Starting browser PhantomJS
07 06 2017 13:27:09.437:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket 4Vq49vX24cDAIZfjAAAA with id 34827962
LOG: undefined
PhantomJS 2.1.1 (Linux 0.0.0) DummyComponent should work FAILED
    invokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:605:36
    onInvokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:154:49
    invokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:604:48
    runTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:372:57
    drainMicroTaskQueue@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:765:42
    run@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17951:29
    /tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17964:31
    flush@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17813:11
    resolvePromise@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:951:78
    resolvePromise@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:921:31
    /tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:998:31
    Expected false to be true, 'should create DummyComponent'.
    src/app/dummy.component.spec.js:21:98

Upvotes: 2

Views: 1333

Answers (3)

bobbyrne01
bobbyrne01

Reputation: 6745

Since my templateUrl file contains an angular form that needed to be setup in my TestBed object ..

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [PageFormComponent],
    imports: [FormsModule]
  }).compileComponents()
    .then(() => {
      fixture = TestBed.createComponent(PageFormComponent);
      pageFormComponentInstance = fixture.componentInstance;
    });
}));

Upvotes: 2

Angelo
Angelo

Reputation: 954

So a couple things, and this might just be my confusion. Does dummy.component.html actually exist?

When you call

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [DummyComponent]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(DummyComponent);
        dummyComponentInstance = fixture.componentInstance;
        console.log('beforeEach done');
      });
  }));

You're basically saying "hey, I have some files I need you to fetch, that's an async operation, please compile that template and then create my fixture.

If that html file doesn't exist ... it will fail during your testbed configuration. I ask because you didn't show that file.

I dropped your code into my test project and it worked fine with an empty template. It also worked with an empty templateUrl file.

If you don't have the file yet, or you don't intend to test the file, you can save overhead costs by avoiding fixture =TestBed.createComponent(DummyComponent) all together. It's very very expensive (you're talking 800~ms vs 15ms), because it creates a lot of additional (and powerful) functionality (like compiling your template to a kind of shadow DOM, as I understand it).

If you do have a dummy.component.html file, and it has elements the dynamic module doesn't know how to interpret, then you can either import the NO_SCHEMA_ERRORS from @angular/core and put that in your configuration TestBed:

...
schemas: [NO_SCHEMA_ERRORS]
...

Or you can just teach the testbed how to provide those elements (generally importing those parts. But again, that's not really your problem. Your problem seems to be dummy.component.html doesn't exist.

Hope this helps.

Upvotes: 0

Mathias Rodriguez
Mathias Rodriguez

Reputation: 318

Would you mind trying something?

Import fakeAsync and tick from @angular/core/testing. Move the .then() body inside the test case, and use fakeAsync() there and let me know how it goes.

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [DummyComponent]
    })
    .compileComponents();
}));

it('should work', fakeAsync(() => {
    fixture = TestBed.createComponent(DummyComponent);
    dummyComponentInstance = fixture.componentInstance;
    tick();

    expect(dummyComponentInstance instanceof DummyComponent).toBe(true, 'should create DummyComponent');
}));

Hope this works for you!

Upvotes: 3

Related Questions