角度2没有供应商在业力/茉莉花测试

时间:2017-02-14 18:10:53

标签: javascript unit-testing angular karma-jasmine

首先我搜索了“没有Http提供程序”,因为错误显示,但我意识到我已经在videoplayer.component中导入了http,但我并没有使用它。但我学到了很多关于模拟服务的知识,特别是the post on an observable abstract mock up非常有帮助。从videoplayer.component中删除http后,我遇到了下一个错误:未定义VideoService。我忘记了测试模块中的导入!在测试组件中解析后,我再次收到“No Provider for HTTP”。

首先我的测试代码( videoplayer.component.spec.ts )与上面的帖子中的模拟

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By }              from '@angular/platform-browser';
import { DebugElement }    from '@angular/core';
import { async } from '@angular/core/testing';

import { AbstractMockObservableService } 
    from '../shared/test/abstract.mock.observable.service';
import { VideoPlayer } from './videoplayer.component';
import { VideoService } from './video.service';

describe('VideoPlayer (inline template)', () => {

    class MockService extends AbstractMockObservableService {
      getLoading(cb) {
      return true;// stubbing?
  }

  pushLoadState() {
      return false;// stubbing?
  }

  getOptions(requestDisplayId) : Observable<VideoDetail> {
      return false;// return Observable???
  }

  reservePlayer(displayID,domID) { // TODO register ids?
      return false;
  }

    }

  let mockService;
  let comp:    VideoPlayer;
  let fixture: ComponentFixture<VideoPlayer>;
  let de:      DebugElement;
  let el:      HTMLElement;

  // async beforeEach
  beforeEach(async(() => {
     mockService = new MockService();
    TestBed.configureTestingModule({
      declarations: [ VideoPlayer ], // declare the test component
      providers:    [ {provide: VideoService, useValue: mockService } ],

  })
  .compileComponents();  // compile template and css
  }));

  // synchronous befareEach...
  beforeEach(() => {
    fixture = TestBed.createComponent(VideoPlayer);

    comp = fixture.componentInstance; // VideoPlayer test instance

    // query for the title <h1> by CSS element selector
    de = fixture.debugElement.query(By.css('.videocontainer'));
    el = de.nativeElement;
    console.log(de);
    console.log(el);
  });
  it('SOME CONTENT', () => {

});

});

现在 videoplayer.component.ts ,请原谅Youtube iFrame-API的直接dom操作,我仍然在寻找与Angular2兼容的方式。

import {Component,Input,Output,Inject,ElementRef} from '@angular/core';
import {NgIf} from '@angular/common';

import {VideoService} from './video.service';

@Component({
    selector: 'my-video-player',
    providers: [VideoService],
    template: require('./videoplayer.html'),
})
export class VideoPlayer implements OnChanges {
    @Input() displayid : String;
    @Input() displayflag : Number;
    // -1 button to load player,0 no display,1 load but dont start, 
    // 2 autostart after load
    @Output() onStateChange = new EventEmitter<any>();

    private options : Object;
    private loadingFlag : boolean;
    private errorFlag : boolean;
    private myPlayer : Object;

    ngOnChanges(changes: SimpleChanges) {
        var refreshed = false;
        if (changes.includes('displayid'))
        {
            let did = changes['displayid'];
            if (did.previousValue !== did.currentValue) {
                refreshPlayer();
                refreshed = true;
            }
        }
        if (!refreshed && changes.includes('displayid'))
        {
            let did = changes['displayflag'];
            if (did.previousValue !== did.currentValue) {
                refreshPlayer();
                refreshed = true;
            }
        }
        /*for (let propName in changes) {
            let chng = changes[propName];
            let cur  = JSON.stringify(chng.currentValue);
            let prev = JSON.stringify(chng.previousValue);
        }*/
    }
  constructor(@Inject(ElementRef) elr: ElementRef,
              @Inject(VideoService) videoService: VideoService) {
      this.loadingFlag = true;
  }

  ngOnInit() {
    refreshPlayer();
  }

  loadPlayer() {
    this.displayflag = 2;
    this.refreshPlayer();
  }

  refreshPlayer() {
      // loadingFlag with Callback
      this.loadingFlag = videoService.getLoading(this.refreshPlayer);
      if (this.loadingFlag) return;
      if (this.myPlayer !== null) {
          this.myPlayer.destroy();
          this.myPlayer = null;
      }
      this.errorFlag = false;
      if (this.displayid !== null && this.displayflag > 0) {
          console.log('refreshPlayer: ' + this.displayid);
          videoService.getOptions(this.displayid)
            .subscribe(
                this.getOptionsOnNext,
                this.getOptionsOnError,
                this.getOptionsOnCompleted
                );
      }
  }
  private getOptionsOnNext(data) {
      this.displayid = data.displayid; //?
      var myId = 'vp'+this.displayid;
      // check if element exists
      if (document.getElementById(myId)===null)
      {
          var newNode = document.createElement("div");
          newNode.id = myId;
          elr.nativeElement.insertBefore(newNode);
      }
      this.options = data.options;
      this.options.events = {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange,
        'onError': onPlayerError,
      };
      this.myPlayer = new YT.Player(myId, options);
      videoService.reservePlayer(this.displayid,myId);
  }
  private getOptionsOnError(err) {
      // console.log(err);
      this.errorFlag = true;
  }
  private getOptionsOnCompleted() {
      console.log('getOptionsOnCompleted: ' + this.displayid);
  }

  private onPlayerReady(event) {
        if (this.displayflag == 2)
            event.target.playVideo();
      }
  private onPlayerStateChange(event) {
        onStateChange.emit(event.data);
      }
  private onPlayerError(event) {
        console.log(event);
        errorFlag = true;
      }
}

这是堆栈跟踪,什么也没告诉我。

    Error: No provider for Http!
    Error: DI Error
        at NoProviderError.ZoneAwareError (webpack:///~/zone.js/dist/zone.js:811:0 <- src/polyfills.ts:3833:33)
        at NoProviderError.BaseError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:22:0 <- src/test.ts:22301:16)
        at NoProviderError.AbstractProviderError [as constructor] (webpack:///~/@angular/core/src/di/reflective_errors.js:54:0 <- src/test.ts:45305:16)
        at new NoProviderError (webpack:///~/@angular/core/src/di/reflective_errors.js:116:0 <- src/test.ts:45367:16)
        at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/src/di/reflective_injector.js:485:0 <- src/test.ts:63446:19)
        at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/src/di/reflective_injector.js:524:0 <- src/test.ts:63485:25)
        at ReflectiveInjector_._getByKey (webpack:///~/@angular/core/src/di/reflective_injector.js:456:0 <- src/test.ts:63417:25)
        at ReflectiveInjector_.get (webpack:///~/@angular/core/src/di/reflective_injector.js:325:0 <- src/test.ts:63286:21)
        at TestBed.get (webpack:///~/@angular/core/bundles/core-testing.umd.js:827:0 <- src/test.ts:8978:67)
        at CompiledTemplate.proxyViewClass.AppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:152:0 <- src/test.ts:64221:45)
        at CompiledTemplate.proxyViewClass.DebugAppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:580:0 <- src/test.ts:64649:49)
        at CompiledTemplate.proxyViewClass.View_VideoPlayer_Host0.createInternal (/DynamicTestModule/VideoPlayer/host.ngfactory.js:19:55)
        at CompiledTemplate.proxyViewClass.AppView.createHostView (webpack:///~/@angular/core/src/linker/view.js:108:0 <- src/test.ts:64177:21)
        at CompiledTemplate.proxyViewClass.DebugAppView.createHostView (webpack:///~/@angular/core/src/linker/view.js:564:0 <- src/test.ts:64633:52)
        at ComponentFactory.create (webpack:///~/@angular/core/src/linker/component_factory.js:202:0 <- src/test.ts:33107:25)

0 个答案:

没有答案