如何监视
clipboard.copy
方法?
对于
const clipboard = TestBed.inject(Clipboard);
spyOn(clipboard, 'copy').and.returnValue(true);
我收到警告
Argument of type '"copy"' is not assignable to parameter of type 'keyof Clipboard'.
这是
CopyToClipboardHost
class CopyToClipboardHost {
public content = '';
public attempts = 1;
public copied = jasmine.createSpy('copied spy');
}
我不知道为什么它在你的案例中不起作用,但我设法创建简单的测试用例并且它工作正常:
import {Component} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {Clipboard} from '@angular/cdk/clipboard';
import createSpyObj = jasmine.createSpyObj;
@Component({
selector: 'app-root',
template: ''
})
export class SampleComponent {
constructor(private clipboard: Clipboard) {
}
copySomething(): void {
this.clipboard.copy('test');
}
}
describe('SampleComponent', () => {
let fixture: ComponentFixture<SampleComponent>;
let component: SampleComponent;
const clipboardSpy = createSpyObj<Clipboard>('Clipboard', ['copy']);
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [SampleComponent],
providers: [{provide: Clipboard, useValue: clipboardSpy}]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SampleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should call clipboard copy', () => {
component.copySomething();
expect(clipboardSpy.copy).toHaveBeenCalledWith('test');
});
});
需要注意的一件事 - 不要将外部模块导入到
TestingModule
,因为您只想测试您的组件,而不是对所需的依赖项进行模拟/监视。
我今天自己遇到了这个问题,它可能只是 Clipboard 类的不同/较新的实现。就我而言,正在使用
navigator.clipboard.writeText(text)
,所以我必须更换
spyOn(clipboard, 'copy').and.returnValue(true);
与
spyOn(clipboard, 'writeText').and.returnValue(true);
希望这对某人(如果不是你)有帮助。
您可以导入 ClipboardModule 并将 Clipboard 提供给 TestBed。然后创建一个间谍复制方法。
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ExampleComponent],
imports: [ NoopAnimationsModule, ClipboardModule],
providers: [ Clipboard ]
}).compileComponents();
});
it('should copy to clipboard', () => {
const clipSpy = spyOn(component.clipboard, 'copy').and.returnValue(true);
component.copy();
expect(clipSpy).toHaveBeenCalled();
});
我遇到了同样的问题。我使用
jest
来测试我的 Angular 应用程序,而不是 jasmine
,所以我需要一个稍微不同的解决方案,但总的来说它反映了 Buczkowski 的解决方案上面:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';
import { FixedWidthTextBoxComponent } from './fixed-width-textbox.component';
describe('FixedWidthTextBoxComponent', () => {
let component: FixedWidthTextBoxComponent;
let fixture: ComponentFixture<FixedWidthTextBoxComponent>;
// I can get along without a spy here. I don't know what I would have
// done had I needed a spy, rather than a mock
const mockWriteText = jest.fn();
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [FixedWidthTextBoxComponent, ClipboardModule],
// I needed to pass an object here, rather than the mock function,
// because I'm using the "CdkCopyToClipboard" directive from Angular
// CDK to handle the copying to the clipboard
providers: [{ provide: Clipboard, useValue: { copy: mockWriteText } }],
}).compileComponents();
fixture = TestBed.createComponent(FixedWidthTextBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('Copies data to the clipboard when the button is clicked', async () => {
component.contents = 'blah blah blah';
component.filename = 'testfile.txt';
component.label = 'Test Label';
fixture.detectChanges();
const buttons: HTMLButtonElement[] =
fixture.nativeElement.querySelectorAll('div button');
let copyButton!: HTMLButtonElement;
buttons.forEach((button) => {
if (button.textContent === 'Copy') {
copyButton = button;
}
});
copyButton.click();
expect(mockWriteText).toHaveBeenCalledWith(component.contents);
});
});