Angular 角度2+;Unitest为窗口注入对象提供指令

Angular 角度2+;Unitest为窗口注入对象提供指令,angular,typescript,testing,angular2-directives,Angular,Typescript,Testing,Angular2 Directives,我试图为一个指令编写一个测试,该指令在其构造函数中接收一个窗口对象 指令代码: import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { Inject } from '@angular/core'; import { Observable,

我试图为一个指令编写一个测试,该指令在其构造函数中接收一个窗口对象

指令代码:

 import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit } from                                             
    '@angular/core';
    import { Inject } from '@angular/core';
    import { Observable, Subscription } from 'rxjs/Rx';


    @Directive({
        selector: '[appFixToViewport]'
    })
    export class FixToViewportDirective implements OnChanges, OnDestroy, OnInit {
    @Input('appFixToViewport') appFixToViewport: boolean;
    @Input('outerMargin') outerMargin: number = 15; // defaults to 15px margin
    private windowResize$: Subscription;

    constructor(private element: ElementRef,
                @Inject('$window') private $window: any) {}

    ngOnInit() {
        this.windowResize$ = Observable.fromEvent(this.$window, 'resize')
            .debounceTime(500)
            .subscribe((event) => {
                this.fixDropdownToViewPort();
            });
    }

    ngOnChanges(changes) {
        if (changes.appFixToViewport.currentValue) {
            this.fixDropdownToViewPort();
        }
    }

    ngOnDestroy() {
        if (this.windowResize$ !== undefined) {
            this.windowResize$.unsubscribe();
        }
    }

    /**
     * Name: fixDropdownToViewPort
     * Purpose: put div element inside the view port
     * Returns: void
     */
    fixDropdownToViewPort() {
        this.$window.requestAnimationFrame(() => {
            this.element.nativeElement.style.transform = ''; // reset transform

            let winWidth = this.$window.innerWidth;
            // Attempt obtaining a more accurate width (excluding scrollbars)
            if (this.$window.document && this.$window.document.body.clientWidth) {
                winWidth = this.$window.document.body.clientWidth;
            }
            let elementWidth = this.element.nativeElement.offsetWidth; // div width

            // div right border absolute position
            let elementRight = this.element.nativeElement.getBoundingClientRect().right;

            // div left border absolute position
            let elementLeft = this.element.nativeElement.getBoundingClientRect().left;

            let delta = 0;

            if (elementRight > winWidth && winWidth > elementWidth) { // calc if the div is overflow right
                delta = elementRight - winWidth + this.outerMargin;
            }
            else if (winWidth < elementWidth) { // calc if the div is bigger then the view port
                delta = elementLeft - this.outerMargin;
            }
            this.element.nativeElement.style.transform = `translateX(${-delta}px)`;
        });
    }
}
import{Directive,ElementRef,Input,OnChanges,OnDestroy,OnInit}from
'角/核';
从“@angular/core”导入{Inject};
从“rxjs/Rx”导入{可观察,订阅};
@指示({
选择器:“[appFixToViewport]”
})
导出类FixtoViewPort指令实现OnChanges、OnDestroy和OnInit{
@输入('appFixToViewport')appFixToViewport:布尔值;
@输入('outerMargin')outerMargin:number=15;//默认为15px边距
私有windowResize$:订阅;
构造函数(私有元素:ElementRef,
@注入('$window')私有$window:any){}
恩戈尼尼特(){
this.windowResize$=可观察的.fromEvent(this.window.$resize')
.debounceTime(500)
.订阅((事件)=>{
this.fixDropdownToViewPort();
});
}
ngOnChanges(更改){
if(changes.appFixToViewport.currentValue){
this.fixDropdownToViewPort();
}
}
恩贡德斯特罗(){
if(this.windowResize$!==未定义){
此.windowResize$.unsubscribe();
}
}
/**
*名称:fixDropdownToViewPort
*用途:将div元素放在视图端口内
*退货:作废
*/
fixDropdownToViewPort(){
此.$window.requestAnimationFrame(()=>{
this.element.nativeElement.style.transform='';//重置转换
设winWidth=this.$window.innerWidth;
//尝试获得更精确的宽度(不包括滚动条)
if(this.$window.document&&this.$window.document.body.clientWidth){
winWidth=this.$window.document.body.clientWidth;
}
让elementWidth=this.element.nativeElement.offsetWidth;//div width
//右边界绝对位置
让elementRight=this.element.nativeElement.getBoundingClientRect().right;
//左边界绝对位置
让elementLeft=this.element.nativeElement.getBoundingClientRect().left;
设δ=0;
if(elementRight>winWidth&&winWidth>elementWidth){//calc如果div是右溢出的
delta=elementRight-winWidth+this.outerMargin;
}
else if(winWidth
当我试图初始化模板中使用指令的测试组件时,我收到了注入错误

以下是测试规范文件:

import {Component, ElementRef, DebugElement} from '@angular/core';
import {TestBed, async, ComponentFixture} from '@angular/core/testing';
import {FixToViewportDirective} from './fixToViewport.directive';
import {createInjector} from "@angular/core/src/view/refs";
import {By} from "@angular/platform-browser";


@Component({
    selector: 'app-test-fixtoviewport',
    template:'<div appFixToViewport="isOpenFlag" ></div>'
    })
class TestFixToViewPort {}


describe('Directive: FixToViewportDirective',()=>{
    let component :TestFixToViewPort
    let fixture : ComponentFixture<TestFixToViewPort>;
    let inputEl: DebugElement;
    const $window= Window;

    beforeEach((()=>{

        TestBed.configureTestingModule({
            declarations: [
                TestFixToViewPort,
                FixToViewportDirective
            ]});

             fixture = TestBed.createComponent(TestFixToViewPort);
             component= fixture.componentInstance;
             inputEl= fixture.debugElement.query(By.css('div'));
        }));
    it('should have a defined component', () => {
        expect(component).toBeDefined();
    });
    })
从'@angular/core'导入{Component,ElementRef,DebugElement};
从“@angular/core/testing”导入{TestBed,async,ComponentFixture};
从“./fixtoview.directive”导入{FixToViewportDirective};
从“@angular/core/src/view/refs”导入{createInjector}”;
从“@angular/platform browser”导入{By}”;
@组成部分({
选择器:“应用程序测试修复视口”,
模板:“”
})
类TestFixToViewPort{}
描述('Directive:FixToViewportDirective',()=>{
let组件:TestFixToViewPort
let夹具:组件夹具;
let inputEl:DebugElement;
const$window=window;
在每个((()=>{
TestBed.configureTestingModule({
声明:[
TestFixToViewPort,
fixtoViewPort指令
]});
fixture=TestBed.createComponent(TestFixtToViewport);
组件=fixture.componentInstance;
inputEl=fixture.debugElement.query(By.css('div'));
}));
它('应该有一个已定义的组件',()=>{
expect(component.toBeDefined();
});
})
以及错误跟踪:

指令:FixToViewportDirective

    × should have a defined component
        Error
            at injectionError (webpack:///~/@angular/core/@angular/core.es5.js:1232:0 <- src/test.ts:1511:86) [angular]
            at noProviderError (webpack:///~/@angular/core/@angular/core.es5.js:1270:0 <- src/test.ts:1549:12) [angular]
            at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/@angular/core.es5.js:2771:0 <- src/test.ts:3050:19) [angular]
            at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/@angular/core.es5.js:2810:0 <- src/test.ts:3089:25) [angular]

        Expected undefined to be defined.
            at Object.<anonymous> (webpack:///src/app/shared/fixViewport/fixToViewportTester.component.spec.ts:42:7 <- src/test.ts:144444:27) [ProxyZone]
            at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:80:0 <- src/test.ts:114788:39) [ProxyZone]
            at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:105:9 <- src/test.ts:114487:34) [<root>]

Chrome 59.0.3071 (Windows 10 0.0.0) Directive: FixToViewportDirective should have a defined component FAILED
        Error
            at injectionError (webpack:///~/@angular/core/@angular/core.es5.js:1232:0 <- src/test.ts:1511:86) [angular]
            at noProviderError (webpack:///~/@angular/core/@angular/core.es5.js:1270:0 <- src/test.ts:1549:12) [angular]
            at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/@angular/core.es5.js:2771:0 <- src/test.ts:3050:19) [angular]
            at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/@angular/core.es5.js:2810:0 <- src/test.ts:3089:25) [angular]
            at ReflectiveInjector_._getByKey (webpack:///~/@angular/core/@angular/core.es5.js:2742:0 <- src/test.ts:3021:25) [angular]
            at ReflectiveInjector_.get (webpack:///~/@angular/core/@angular/core.es5.js:2611:0 <- src/test.ts:2890:21) [angular]
            at DynamicTestModuleInjector.NgModuleInjector.get (webpack:///~/@angular/core/@angular/core.es5.js:3579:0 <- src/test.ts:3858:52) [angular]
            at resolveDep (webpack:///~/@angular/core/@angular/core.es5.js:11040:0 <- src/test.ts:11319:45) [angular]
            at createClass (webpack:///~/@angular/core/@angular/core.es5.js:10896:0 <- src/test.ts:11175:91) [angular]
            at createDirectiveInstance (webpack:///~/@angular/core/@angular/core.es5.js:10724:0 <- src/test.ts:11003:37) [angular]
            at createViewNodes (webpack:///~/@angular/core/@angular/core.es5.js:12087:29 <- src/test.ts:12366:49) [angular]
            at callViewAction (webpack:///~/@angular/core/@angular/core.es5.js:12531:0 <- src/test.ts:12810:13) [angular]
            at execComponentViewsAction (webpack:///~/@angular/core/@angular/core.es5.js:12440:0 <- src/test.ts:12719:13) [angular]
            at createViewNodes (webpack:///~/@angular/core/@angular/core.es5.js:12114:0 <- src/test.ts:12393:5) [angular]
        Expected undefined to be defined.
            at Object.<anonymous> (webpack:///src/app/shared/fixViewport/fixToViewportTester.component.spec.ts:42:7 <- src/test.ts:144444:27) [ProxyZone]
            at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:80:0 <- src/test.ts:114788:39) [ProxyZone]
            at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:105:9 <- src/test.ts:114487:34) [<root>]

Chrome 59.0.3071 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (1.053 secs / 0.076 secs)
×应具有已定义的组件
错误

在injectionError(网页包:///~/@angular/core/@angular/core.es5.js:1232:0尝试向测试模块添加
ElementRef

 TestBed.configureTestingModule({
            declarations: [
                TestFixToViewPort,
                FixToViewportDirective
            ],
            imports: [ ElementRef ]
});

看一看这位朋友:我知道这个解释并实际遵循了它,然后遇到了这个注入问题,我无法解决,这个解释没有提到指令在其构造函数中有注入的情况。我尝试按照您的建议导入ElementRef,运行测试导致以下错误:指令:FixToViewportDirective×应具有定义的组件错误:模块“DynamicTestModule”导入的意外值“ElementRef”。请添加@NgModule注释。在syntaxError处。。。。