我有一条指令可以复制到剪贴板。当我正常使用它时,它可以工作,但是当我想对其进行一些测试时,@ Input属性始终未定义
这是指令 CopyClipboard.directive.ts
import { Directive, Input, Output, EventEmitter, HostListener } from '@angular/core';
/**
* Directive use to copy the content of the event to the clipBoard
* Source :
* https://stackoverflow.com/a/52949299/5703228
*
* @export
* @class CopyClipboardDirective
*/
@Directive({
selector: '[appCopyClipboard]'
})
export class CopyClipboardDirective {
constructor() {}
@Input('appCopyClipboard')
public payload: string;
@Output() public copied: EventEmitter<string> = new EventEmitter<string>();
@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
event.preventDefault();
if (this.payload == null) {
return;
}
const listener = (e: ClipboardEvent) => {
const clipboard = e.clipboardData || window['clipboardData'];
clipboard.setData('text', this.payload.toString());
e.preventDefault();
this.copied.emit(this.payload);
};
document.addEventListener('copy', listener, false);
document.execCommand('copy');
document.removeEventListener('copy', listener, false);
}
}
这是对应的测试 Copyclipboard.directive.spec.ts
/* tslint:disable:no-unused-variable */
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { CopyClipboardDirective } from './CopyClipboard.directive';
import { Component, DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { TestUtils } from 'src/app/tests/test-utils';
@Component({
template: '<button [appCopyClipboard]="getTextToCopy()" (copied)="onCopied($event)">Test button</button>'
})
class TestCopyClipboardDirectiveComponent {
public textToCopy = 'Test Text';
public textCopied = '';
public onCopied(textCopied: string): void {
this.textCopied = textCopied;
}
public getTextToCopy(): string {
return this.textToCopy;
}
}
describe('Directive: CopyClipboardDirective', () => {
let component: TestCopyClipboardDirectiveComponent;
let fixture: ComponentFixture<TestCopyClipboardDirectiveComponent>;
let buttonDe: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
CopyClipboardDirective,
TestCopyClipboardDirectiveComponent
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestCopyClipboardDirectiveComponent);
component = fixture.componentInstance;
fixture.detectChanges();
buttonDe = fixture.debugElement.query(By.css('button'));
});
it('should be created', () => {
expect(component).toBeTruthy();
expect(buttonDe).toBeTruthy();
});
it('should call callback after copy on click', () => {
spyOn(component, 'onCopied').and.callThrough();
const buttonNe: HTMLElement = buttonDe.nativeElement;
buttonNe.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.onCopied).toHaveBeenCalledTimes(1);
expect(component.onCopied).toHaveBeenCalledWith(component.textToCopy);
expect(component.textCopied).toBe(component.textToCopy);
});
});
// We cannot access content of ClipBoard as it is a security violation
// So we cannot test if the data is actually in the clipBoard
// But we can try to listen for event copy
it('should emit copy event on document', (done: DoneFn) => {
spyOn(component, 'onCopied').and.callThrough();
let success = false;
const listener = (e: ClipboardEvent) => {
success = true;
done();
document.removeEventListener('copy', listener, false);
};
document.addEventListener('copy', listener, false);
const buttonNe: HTMLElement = buttonDe.nativeElement;
buttonNe.click();
fixture.detectChanges();
/*fixture.whenStable().then(() => {
expect(success).toBe(true);
});*/
});
});
最后一次测试均失败。
当我调试执行程序时,我看到指令中的payload
未定义。
为什么指令@Input在测试中未定义?
我在组件中的其他地方使用它,并且效果很好:
<button mat-raised-button color="secondary"
[appCopyClipboard]="getStringFormattedQuotation()"
(copied)="notifyCopied($event)">
<mat-icon>file_copy</mat-icon> Copier
</button>
**编辑** 我按照建议尝试将测试组件模板更改为此:
...[appCopyClipboard]=" \'someText string here\' "...
有了这个,我将@Input设置为此值,但是在指令代码中,仍然永远不会调用文档上设置的侦听器。 我试图删除该行
document.removeEventListener('copy', listener, false);
进行测试,但也没有用。 我注意到的另一件事是在浏览器的控制台中,我得到了两行:
zone.js:3401 Access to XMLHttpRequest at 'ng:///DynamicTestModule/TestCopyClipboardDirectiveComponent.ngfactory.js' from origin 'http://localhost:9876' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
我的其他任何测试都没有收到此错误。