Prakash
Prakash

Reputation: 123

AngularJS 2 unit testing component with jasmine facing error, Cannot read property 'firstChild' of null

I am writing unit test for my angular 2 application, I am trying to test the component I made. I am referring to a sample git repository for writing test cases in angular 2 using TypeScript and Jasmine framework. I did same what is done in sample repository (https://github.com/juliemr/ng2-test-seed) to test my component but i get following error.

TypeError: Cannot read property 'firstChild' of null
at Object.el (http://127.0.0.1:9090/node_modules/angular2/bundles/testing.dev.js:537:29)
at TestComponentBuilder.createAsync (http://127.0.0.1:9090/node_modules/angular2/bundles/testing.dev.js:841:28)
at eval (http://127.0.0.1:9090/app/test/search.component.specs_test.js:95:32)
at FunctionWrapper.apply (http://127.0.0.1:9090/node_modules/angular2/bundles/angular2.dev.js:327:17)
at FunctionWithParamTokens.execute (http://127.0.0.1:9090/node_modules/angular2/bundles/testing.dev.js:1947:37)
at TestInjector.execute (http://127.0.0.1:9090/node_modules/angular2/bundles/testing.dev.js:1868:17)
at Object.<anonymous> (http://127.0.0.1:9090/node_modules/angular2/bundles/testing.dev.js:2006:44)
at attemptAsync (http://127.0.0.1:9090/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1916:24)
at QueueRunner.run (http://127.0.0.1:9090/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1871:9)
at http://127.0.0.1:9090/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1898:16

My component is like this:

@Component({
  selector: 'search',
  templateUrl: 'app/html/search.component.html',
  styleUrls: ['app/css/search.css'],
  providers: [SearchService,SearchUtil],
  directives: [OverviewComponent]
})
export class SearchComponent {}

My unit test case looks like this:

it('should populate search suggestions UI', injectAsync([TestComponentBuilder,SearchComponent], (tcb) => {
    return tcb.createAsync(SearchComponent).then((fixture) => {
      fixture.detectChanges();
      var compiled = fixture.debugElement.nativeElement;

      compiled.querySelector('search').value('teachers');
      fixture.detectChanges();

      var compiled = fixture.debugElement.nativeElement;

      console.log(compiled.querySelector('search').value()+" = "+compiled.querySelector('.searchlist>a').length);

      expect(compiled.querySelector('.searchlist>a').length).toBeGreaterThan(1);
    });
  }));

I am getting error, in this line - tcb.createAsync(SearchComponent), says the object is null.

Upvotes: 1

Views: 2058

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202138

You don't need to specify SearchComponent into the first parameter of the injectAsync function:

it('should populate search suggestions UI', 
       injectAsync([TestComponentBuilder], (tcb) => {
  return tcb.createAsync(SearchComponent).then((fixture) => {
    (...)
  });
}));

Edit

You also need to the base test providers, as described below:

import {setBaseTestProviders} from 'angular2/testing';

import {
  TEST_BROWSER_PLATFORM_PROVIDERS,
  TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';

describe('Some tests', () => {
  setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, 
                   TEST_BROWSER_APPLICATION_PROVIDERS);
  (...)
});

Edit1

You need to register the providers your component will use (directly or indirectly) using the beforeEachProviders function.

Here is a sample:

beforeEachProviders(() => {
  return [
    HTTP_PROVIDERS,
    provide(XHRBackend, { useClass: MockBackend }),
    HttpService
  ];
});

Upvotes: 2

Related Questions