【发布时间】:2020-08-04 06:08:17
【问题描述】:
更新
再看久一点,原来最初的错误是因为在我的笑话设置中缺少 BrowserDynamicTestingModule .. 还有一些方法可以将模拟 ElementRef 作为提供者传递以消除错误。 但是,执行其中任何一项都不会导致测试实际工作。我创建了一个新项目,除了这个指令之外什么都没有添加,所以它不是开玩笑的,我仍然无法获得一组通过的测试。
--
由于某种原因,当我将指令添加到测试平台声明中时,我得到:
This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors
我希望这个指令和规范起作用
指令
import {
Directive,
ElementRef,
Output,
EventEmitter,
HostListener
} from '@angular/core'
@Directive({
selector: '[common-click-outside]'
})
export class ClickOutsideDirective {
@Output('common-click-outside') clickOutsideEmitter: EventEmitter<
any
> = new EventEmitter()
constructor (private _elementRef: ElementRef) {}
@HostListener('document:click', ['$event.target']) onClick (
targetElement: ElementRef
) {
const isClickedInside = this._elementRef.nativeElement.contains(
targetElement
)
if (!isClickedInside) this.clickOutsideEmitter.next()
}
}
规格
import { ElementRef, Component, DebugElement } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
import { ClickOutsideDirective } from './click-outside.directive'
@Component({
template: `
<div class="parent">
<div class="inside" (common-click-outside)="directiveDidFire = true">
<span class="inner-child"></span>
</div>
<div class="outside"></div>
</div>
`
})
class MockClickOutsideComponent {
directiveDidFire: boolean
}
describe('ClickOutsideDirective', () => {
let fixture: ComponentFixture<MockClickOutsideComponent>
let component: MockClickOutsideComponent
let insideEl: DebugElement
let innerChildEl: DebugElement
let outsideEl: DebugElement
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [MockClickOutsideComponent, ClickOutsideDirective]
})
fixture = TestBed.createComponent(MockClickOutsideComponent)
component = fixture.componentInstance
insideEl = fixture.debugElement.query(By.css('.inside'))
innerChildEl = fixture.debugElement.query(By.css('.inner-child'))
outsideEl = fixture.debugElement.query(By.css('.outside'))
})
it('should create an instance', () => {
const insideEl = document.createElement('div')
const insideElRef = new ElementRef<HTMLElement>(insideEl)
const directive = new ClickOutsideDirective(insideElRef)
expect(directive).toBeDefined()
})
it('should emit on click outside', () => {
outsideEl.triggerEventHandler('click', null)
fixture.detectChanges()
expect(component.directiveDidFire).toBeTruthy()
})
it('should not emit on click inside', () => {
insideEl.triggerEventHandler('click', null)
fixture.detectChanges()
expect(component.directiveDidFire).toBeFalsy()
})
it('should not emit on click of child of inside element', () => {
innerChildEl.triggerEventHandler('click', null)
fixture.detectChanges()
expect(component.directiveDidFire).toBeFalsy()
})
})
【问题讨论】: