我具有以下指令,该指令使用copy-to-clipboard
属性添加到元素中,并在单击时将该属性的内容复制到用户剪贴板:
@Directive({
selector: '[copy-to-clipboard]'
})
export class CopyToClipboardDirective {
@Input('copy-to-clipboard') public payload: string;
@HostListener('click', ['$event'])
onClick(event: MouseEvent): void {
event.preventDefault();
if (!this.payload) {
return;
}
const listener = (e: ClipboardEvent) => {
const clipboard = e.clipboardData;
clipboard.setData('text', this.payload.toString());
e.preventDefault();
};
document.addEventListener('copy', listener, false);
document.execCommand('copy');
document.removeEventListener('copy', listener, false);
}
}
我的单元测试设置如下:
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {CopyToClipboardDirective} from './copy-to-clipboard.directive';
import {Component} from '@angular/core';
@Component({
template: `<input [copy-to-clipboard]="'this is the passed string'" role="button" type="button">`
})
class MockCopyToClipboardComponent {}
fdescribe('Directive: CopyToClipboard', () => {
let fixture: ComponentFixture<MockCopyToClipboardComponent>;
let component: MockCopyToClipboardComponent;
let element;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CopyToClipboardDirective, MockCopyToClipboardComponent]
});
fixture = TestBed.createComponent(MockCopyToClipboardComponent);
element = fixture.debugElement.nativeElement;
component = fixture.componentInstance;
});
it('should run the copy command', () => {
spyOn(document, 'execCommand');
element.querySelector('input').click();
fixture.detectChanges();
expect(document.execCommand).toHaveBeenCalled();
});
});
我得到一个错误,说预期条件永远不会发生。我正在尝试设置测试以确认实际上已经调用了document.execCommand
,并且不确定如何确认复制的值与输入字符串的值匹配吗?
答案 0 :(得分:1)
我运行了您的测试,发现CopyToClipboardDirective#payload
的值从未设置过。您可以通过将fixture.detectChanges()
放在beforeEach
函数的末尾来完成这项工作。
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CopyToClipboardDirective, MockCopyToClipboardComponent]
});
fixture = TestBed.createComponent(MockCopyToClipboardComponent);
element = fixture.debugElement.nativeElement;
component = fixture.componentInstance;
fixture.detectChanges(); // >>>>>> ADD this line
});
it('should run the copy command', () => {
spyOn(document, 'execCommand');
element.querySelector('input').click();
// fixture.detectChanges(); // >>>>>> REMOVE this line
expect(document.execCommand).toHaveBeenCalledWith('copy');
});
要检查将什么文本复制到剪贴板,可以尝试使用Clipboard#readText
读回。由于readText
返回Promise
,因此您需要处理其异步性质。以下示例使用done
函数执行此操作。
it('should run the copy command', (done) => {
spyOn(document, 'execCommand');
element.querySelector('input').click();
expect(document.execCommand).toHaveBeenCalledWith('copy');
element.querySelector('input').focus();
navigator.clipboard.readText()
.then(t => {
expect(t).toBe('this is the passed string');
done();
})
.catch(err => {
fail(err);
});
});