带有茉莉花的AngularJS 2单元测试组件面临错误,无法读取null的属性'firstChild'

Posted

技术标签:

【中文标题】带有茉莉花的AngularJS 2单元测试组件面临错误,无法读取null的属性\'firstChild\'【英文标题】:AngularJS 2 unit testing component with jasmine facing error, Cannot read property 'firstChild' of null带有茉莉花的AngularJS 2单元测试组件面临错误,无法读取null的属性'firstChild' 【发布时间】:2016-08-01 10:55:06 【问题描述】:

我正在为我的 Angular 2 应用程序编写单元测试,我正在尝试测试我制作的组件。我指的是一个示例 git 存储库,用于使用 TypeScript 和 Jasmine 框架以 Angular 2 编写测试用例。我做了与示例存储库中相同的操作 (https://github.com/juliemr/ng2-test-seed) 来测试我的组件,但出现以下错误。

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

我的组件是这样的:

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

我的单元测试用例如下所示:

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);
    );
  ));

我收到错误,在这一行 - tcb.createAsync(SearchComponent),说对象为空。

【问题讨论】:

【参考方案1】:

injectAsync函数的第一个参数不需要指定SearchComponent

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

编辑

您还需要基础测试提供者,如下所述:

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);
  (...)
);

编辑1

您需要使用beforeEachProviders 函数注册您的组件将使用(直接或间接)的提供程序。

这是一个示例:

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

【讨论】:

已经尝试过你前面提到的方式,但运气不好,我得到了同样的错误。 我尝试了这些更改,但现在我收到此错误,No provider for Token DocumentToken! 您是否使用beforeEachProviders 函数设置了您需要的提供程序?尤其是DocumentToken一个... 是的,我的测试代码中有它,beforeEachProviders(() =&gt; return [ SearchService, RouteRegistry,DirectiveResolver,ViewResolver, provide(Location, useClass: SpyLocation ), provide(ROUTER_PRIMARY_COMPONENT, useValue: EnterpriseSearchComponent ), provide(Router, useClass: RootRouter ), SearchService, Jsonp, SearchUtil, SearchComponent, JSONP_PROVIDERS, Solrconfig, AppConfig, TestComponentBuilder ] ); 嘿,我在 beforeEachProviders 中添加了这两个 TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS,现在测试失败了,这意味着它可以工作:),谢谢你的帮助

以上是关于带有茉莉花的AngularJS 2单元测试组件面临错误,无法读取null的属性'firstChild'的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript - 茉莉花 - Chutzpah - AngularJS

reactjs中组件的单元测试功能使用业力和茉莉花

用茉莉花测试angularjs es6工厂

如何在茉莉花中为可观察的 finally 块编写单元测试 - Angular 2

typescript 简单的茉莉花单元测试,测试基本功能

单元测试茉莉花@NGRX/DATA