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处。。。。